HID via Leonardo testing

Added by J. Simmons almost 6 years ago

Home of J's work to implement HID through Leonardo style boards controlled from CHIP.

Tasked under DEV-07: Test Keyboard USB HID over Arduino, with all sub-PBIs tasked onto 2017 Sprint 2.


Replies (9)

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

This week I committed to documenting my initial research into powering CHIP Pro from a Feather (our preferred Leonardo style board) and providing I2C between CHIP Pro and Feather (to enable command and control of the Feather from the CHIP Pro).

Powering CHIP Pro from a Feather
  • https://docs.getchip.com/chip_pro.html#power-c-h-i-p-pro
    There are several power options listed in the CHIP Pro docs. Given we may later use a battery to provide power for graceful shutdown, I am going to go with the "Connect 5 - 5.5 volts of power to CHG-IN (and GND)" on the CHIP Pro side.
  • https://learn.adafruit.com/assets/30918
    We can get 5v (up to 500mA) from the USB pin on the Feather and there are mutliple GND pins we can use.
  • Plan: connect Feather.USB pin to CHIP.CHG-IN pin and connect a Feather.GND pin to a CHIP.GND pin to provide power
Providing I2C between CHIP Pro and Feather

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Today I am planning to test implementing the Holoseat controller (and specifically the required connections for HID through Arduino-like devices) with the CHIP Pro/Python. My test plan is as follows.

  1. Prep CHIP Pro
    1. Install antenna
    2. Install Debian os
    3. Setup wifi
    4. Setup ssh
    5. Test ssh (need IP address)
  2. Test power from feather
    1. Power down CHIP Pro
    2. Wire up proposed power pinout from feather to CHIP Pro
    3. Connect feather to power supply
    4. Observe CHIP Pro
    5. If it starts, try to ssh into it
  3. Setup python IO chiptainer
    1. Continue getting power from feather
    2. Install Docker
    3. Pull python IO image
    4. Launch python IO container with i2c and mem access
    5. Verify devices are present
    6. Install git in chiptainer
    7. Shutdown chiptainer and chip Pro
  4. Prep feather i2c
    1. Disconnect power pins for chip pro
    2. Install sample firmware (ensure code references built in led)
    3. Disconnect feather from pc
    4. Wire up power and i2c between feather and chip Pro
  5. Test i2c
    1. Plug feather into pc
    2. Verify feather and chip Pro boot
    3. Ssh into chip Pro
    4. Start python IO container
    5. Get python demo source code and required libraries (note, there are two implementations, will test adafruit pure python first)
    6. Modify for wired i2c bus
    7. Run python test code

Here goes...

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Prep CHIP Pro
  1. Install antenna - check
  2. Install Debian os - check
  3. Setup wifi - check (see this post for full details for this step
  4. Setup ssh - already configured in Debian OS for CHIP Pro
  5. Test ssh (need IP address) - check

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Test power from feather
  1. Power down CHIP Pro - check
  2. Wire up proposed power pinout from feather to CHIP Pro
    - 5V from Arduino to pin 4 (CHG-IN)
    - GND from Arduino to pin 6 (GND)
  3. Connect feather to power supply - check
  4. Observe CHIP Pro - power led came on and ping to ip address successful after waiting for it to boot
  5. If it starts, try to ssh into it - check

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Setup python IO chiptainer
  1. Continue getting power from feather - check
  2. Install Docker
    - the CHIP Pro kept shutting down during the installation process
    - it turns out I am short a feather, so I am trying these steps out a Leonardo I have_)
    - I think the CHIP Pro is shutting down because I am drawing too much power, ntc recommends 5v and 1 amp for power supplies
    - looking at the feather docs it looks like it will have the same problem
    - I think we will need to pull power directly from the USB cable
    - going to install Docker with power from the USB port on the CHIP Pro and go back to Leonardo power for i2c tests
  3. Pull python IO image
    - docker pull modelb/chiptainer_python_io:master
  4. Launch python IO container with i2c and mem access
    - docker run -v /sys:/sys --cap-add SYS_RAWIO --device /dev/mem --device /dev/i2c-0 --device /dev/i2c-1 -it modelb/chiptainer_python_io:master
  5. Verify devices are present - check
  6. Install git in chiptainer
    - apk update
    - apk add git
  7. Shutdown chiptainer and chip Pro - check

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Prep feather i2c
  1. Disconnect power pins for chip pro - check
  2. Install sample firmware (ensure code references built in led)
    - see https://oscarliang.com/raspberry-pi-arduino-connected-i2c/
    - check
  3. Disconnect feather from pc - check
  4. Wire up power and i2c between feather and chip Pro - check

Connections for i2c testing

Purpose CHIP Pro Leonardo
5v Pin 4 5v
GND Pin 6 GND
i2c clock Pin 11 SCL
i2c data Pin 12 SDA

Note, we are connecting to i2c-1 on the CHIP Pro.

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Test i2c
  1. Plug feather into pc - check
  2. Verify feather and chip Pro boot - check
  3. Ssh into chip Pro
    - the CHIP Pro is very slow to respond
  4. Start python IO container -check
  5. Get python demo source code and required libraries (note, there are two implementations, will test adafruit pure python first)
    - first lib to check: https://github.com/fordsfords/Adafruit_Python_PureIO
    - example: https://oscarliang.com/raspberry-pi-arduino-connected-i2c/
  6. Modify for wired i2c bus
    import Adafruit_PureIO.smbus as smbus
    import time
    # for RPI version 1, use "bus = smbus.SMBus(0)" 
    bus = smbus.SMBus(1)
    
    # This is the address we setup in the Arduino Program
    address = 0x04
    
    def writeNumber(value):
        bus.write_byte(address, value)
        # bus.write_byte_data(address, 0, value)
        return -1
    
    def readNumber():
        number = bus.read_byte(address)
        # number = bus.read_byte_data(address, 1)
        return number
    
    while True:
        var = input("Enter 1 - 9: ")
        if not var:
            continue
    
        writeNumber(var)
        print "CHIP Pro: Hi Arduino, I sent you ", var
        # sleep one second
        time.sleep(1)
    
        number = readNumber()
        print "Arduino: Hey CHIP Pro, I received a digit ", number
        print
    
  7. Run python test code - check

And it worked! I can see the Arduino receiving messages in the Serial Monitor and I can see the CHIP Pro receiving messages in the ssh session to the CHIP Pro!!!

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

Note, I have done some earlier testing demonstrating that the Leonardo style boards (including the Feather) can dynamically turn on and off their HID modes inside of loop(). These tests plus the testing above clearly demonstrates we can implement HID using Arduino. We just need to resolve the power issue (which note, was not a problem when I was not trying to install large packages) and implement a control protocol over i2c to send HID commands.

I also need to verify the issues with responsiveness (which were not present when I started) are not a chronic issue. I will start working on a Holoseat HID over i2c protocol so we can get this thing fully prototyped.

RE: HID via Leonardo testing - Added by J. Simmons over 5 years ago

I think the responsiveness issue is something to do with my laptop. Everything is starting to feel sluggish.

I made a couple of modifications to the source code for the Leonardo firmware and the Python demo script to move us to HID testing.

Leonard Firmware

#include <Wire.h>
#include <Keyboard.h>

#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;

void setup() {
  Keyboard.begin();
  pinMode(13, OUTPUT);
  Serial.begin(9600); // start serial for output
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  Serial.println("Ready!");
}

void loop() {
  delay(100);
}

// callback for received data
void receiveData(int byteCount) {

  while (Wire.available()) {
    number = Wire.read();
    Serial.print("data received: ");
    Serial.write(number);
    Serial.println("");
    Keyboard.write(number);

    if (number == 1) {

      if (state == 0) {
        digitalWrite(13, HIGH); // set the LED on
        state = 1;
      }
      else {
        digitalWrite(13, LOW); // set the LED off
        state = 0;
      }
    }
  }
}

// callback for sending data
void sendData() {
  Wire.write(number);
}

Python Demo

import Adafruit_PureIO.smbus as smbus
import time
# for RPI version 1, use "bus = smbus.SMBus(0)" 
bus = smbus.SMBus(1)

# This is the address we setup in the Arduino Program
address = 0x04

def writeNumber(value):
    bus.write_byte(address, value)
    # bus.write_byte_data(address, 0, value)
    return -1

def readNumber():
    number = bus.read_byte(address)
    # number = bus.read_byte_data(address, 1)
    return number

while True:
    var = input("Enter a message: ")
    if not var:
        continue

    for c in var:
        writeNumber(ord(c))

Using this code, I can remotely type messages from a machine running ssh into the CHIP Pro to a machine with the Leonardo plugged into it. Note, the Keyboard.write() calls are good for sending what you are typing, but not for game play. We will still need to use Keyboard.press() function for game play. With this last test, I feel we can claim done on the following PBIs.

  • DEV-26: Determine wiring to power CHIP Pro from Feather - with the lesson learned that we should look into drawing power straight off of the USB line
  • DEV-27: Determine wiring to provide I2C between CHIP Pro and Feather
  • DEV-28: Develop Feather code to be I2C slave
  • DEV-29: Develop Johnny-Five code for CHIP Pro to be I2C master - with the understanding that we are now moving to Python 2.7 and CHIP-IO
  • DEV-30: Test master to slave and slave to master events between Feather and CHIP Pro

Part of the implementation of the CHIP Pro version of Holoseat will need to include developing a protocol between the CHIP Pro and the Feather. This protocol should support operation messages from the CHIP Pro to the Feather (e.g. press a key, disable keyboard, release keys, etc) and messages from the Feather to the CHIP Pro (e.g. passing along messages from host machine to the Holoseat over the Holoseat Serial Protocol).

Still, not a bad day's work. *

(1-9/9)