This commit is contained in:
James Wood 2020-09-15 21:05:05 +10:00
parent 83457b3391
commit 1ebf27ec37
17 changed files with 566 additions and 43 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.DS_Store
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

7
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

View File

@ -1,43 +0,0 @@
#include "HID-Project.h"
#include <EasyTransfer.h>
EasyTransfer ET;
int numberOfButtons = 32;
struct RECEIVE_DATA_STRUCTURE{
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t joyx;
int16_t joyy;
int8_t joyz;
int16_t joyxr;
int16_t joyyr;
int8_t joyzr;
uint32_t buttonState;
};
RECEIVE_DATA_STRUCTURE controllerState;
void setup() {
Gamepad.begin();
Serial1.begin(2000000);
ET.begin(details(controllerState), &Serial1);
Gamepad.releaseAll();
}
void loop() {
if(ET.receiveData()){
Gamepad.xAxis(controllerState.joyx);
Gamepad.yAxis(controllerState.joyy);
Gamepad.zAxis(controllerState.joyz);
Gamepad.rxAxis(controllerState.joyxr);
Gamepad.ryAxis(controllerState.joyyr);
Gamepad.rzAxis(controllerState.joyzr);
for (int i=0; i<numberOfButtons; i++){
if(bitRead(controllerState.buttonState, i)){
Gamepad.press(i+1);
} else {
Gamepad.release(i+1);
}
}
Gamepad.write();
}
}

View File

@ -1 +1,7 @@
# HID-Gamepad-USB
## Warning: does not upload from Platformio. I can't figure it out.
USB gamepad/joystick interface for the small ATMEGA16U2 microcontroller on an Arduino Uno. Requires the [Hoodloader2 bootloader](https://github.com/NicoHood/HoodLoader2) to be installed.
Receives joystick position/button info from the ATMEGA328P (the large microcontroller) via a high-speed serial link.

View File

@ -0,0 +1,40 @@
{
"build": {
"flags": "-DUSB_VID=0x2341 -DUSB_PID=0x484C -DUSB_MANUFACTURER='Nico Hood' -DUSB_PRODUCT='HoodLoader2 16u2' -DMAGIC_KEY_POS=RAMEND-1 -DUSB_EP_SIZE=16",
"core": "arduino",
"f_cpu": "16000000L",
"hwids": [
[
"0x2341",
"0x484C"
]
],
"usb_product": "HoodLoader2 16u2",
"usb_manufacturer": "Nico Hood",
"mcu": "atmega16u2",
"variant": "HoodLoader2"
},
"frameworks": [
"arduino",
"simba"
],
"fuses": {
"efuse": "0xFC",
"hfuse": "0xD8",
"lfuse": "0xEF",
"lock": "0x0F",
"unlock": "0x3F"
},
"name": "HoodLoader2 16u2",
"upload": {
"maximum_ram_size": 512,
"maximum_size": 12288,
"protocol": "avr109",
"disable_flushing": true,
"require_upload_port": true,
"wait_for_upload_port": true,
"speed": 57600
},
"url": "http://www.arduino.org/products/boards/4-arduino-boards/arduino-uno",
"vendor": "Arduino"
}

View File

@ -0,0 +1,87 @@
#include "EasyTransfer.h"
//Captures address and size of struct
void EasyTransfer::begin(uint8_t * ptr, uint8_t length, Stream *theStream){
address = ptr;
size = length;
_stream = theStream;
//dynamic creation of rx parsing buffer in RAM
rx_buffer = (uint8_t*) malloc(size+1);
}
//Sends out struct in binary, with header, length info and checksum
void EasyTransfer::sendData(){
uint8_t CS = size;
_stream->write(0x06);
_stream->write(0x85);
_stream->write(size);
for(int i = 0; i<size; i++){
CS^=*(address+i);
_stream->write(*(address+i));
}
_stream->write(CS);
}
boolean EasyTransfer::receiveData(){
//start off by looking for the header bytes. If they were already found in a previous call, skip it.
if(rx_len == 0){
//this size check may be redundant due to the size check below, but for now I'll leave it the way it is.
if(_stream->available() >= 3){
//this will block until a 0x06 is found or buffer size becomes less then 3.
while(_stream->read() != 0x06) {
//This will trash any preamble junk in the serial buffer
//but we need to make sure there is enough in the buffer to process while we trash the rest
//if the buffer becomes too empty, we will escape and try again on the next call
if(_stream->available() < 3)
return false;
}
if (_stream->read() == 0x85){
rx_len = _stream->read();
//make sure the binary structs on both Arduinos are the same size.
if(rx_len != size){
rx_len = 0;
return false;
}
}
}
}
//we get here if we already found the header bytes, the struct size matched what we know, and now we are byte aligned.
if(rx_len != 0){
while(_stream->available() && rx_array_inx <= rx_len){
rx_buffer[rx_array_inx++] = _stream->read();
}
if(rx_len == (rx_array_inx-1)){
//seem to have got whole message
//last uint8_t is CS
calc_CS = rx_len;
for (int i = 0; i<rx_len; i++){
calc_CS^=rx_buffer[i];
}
if(calc_CS == rx_buffer[rx_array_inx-1]){//CS good
memcpy(address,rx_buffer,size);
rx_len = 0;
rx_array_inx = 0;
return true;
}
else{
//failed checksum, need to clear this out anyway
rx_len = 0;
rx_array_inx = 0;
return false;
}
}
}
return false;
}

View File

@ -0,0 +1,63 @@
/******************************************************************
* EasyTransfer Arduino Library
* details and example sketch:
* http://www.billporter.info/easytransfer-arduino-library/
*
* Brought to you by:
* Bill Porter
* www.billporter.info
*
* See Readme for other info and version history
*
*
*This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
<http://www.gnu.org/licenses/>
*
*This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
*To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or
*send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
******************************************************************/
#ifndef EasyTransfer_h
#define EasyTransfer_h
//make it a little prettier on the front end.
#define details(name) (byte*)&name,sizeof(name)
//Not neccessary, but just in case.
#if ARDUINO > 22
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Stream.h"
//#include <NewSoftSerial.h>
//#include <math.h>
//#include <stdio.h>
//#include <stdint.h>
//#include <avr/io.h>
class EasyTransfer {
public:
void begin(uint8_t *, uint8_t, Stream *theStream);
//void begin(uint8_t *, uint8_t, NewSoftSerial *theSerial);
void sendData();
boolean receiveData();
private:
Stream *_stream;
//NewSoftSerial *_serial;
uint8_t * address; //address of struct
uint8_t size; //size of struct
uint8_t * rx_buffer; //address for temporary storage and parsing buffer
uint8_t rx_array_inx; //index for RX parsing buffer
uint8_t rx_len; //RX packet length according to the packet
uint8_t calc_CS; //calculated Chacksum
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,61 @@
/******************************************************************
* EasyTransfer Arduino Library v1.7
* details and example sketch:
* http://www.billporter.info/easytransfer-arduino-library/
*
* Brought to you by:
* Bill Porter
* www.billporter.info
*
* Lib version history
* 1.0 Created
* 1.1 Fixed dumb Copy-paste error in header file
* Added a keyword file
* 1.5 Forked lib into Software and Hardware Serial branches, I don't know a better way
* added passing in of Serial port of different types
* 1.6 Fixed bug where it wasn't clearing out the buffers if the CheckSum failed,
* I'm good at dumb mistakes
* 1.7 Fixed a bug where the receive function could block for too long and never process data correctly
* Organized the examples to be Arduino IDE compatible
* 1.8
* Now Arduino 1.0 compatible!
*
*
* Limits of the Library
* You can change the Serial port,
* but the Struct size must not pass 255 bytes
*
* The protcol is as follows:
* Header(0x06,0x85),SizeofPayload,Payload,Checksum
*
*
*This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
<http://www.gnu.org/licenses/>
*
*This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
*To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or
*send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
******************************************************************/
********************To Install*************************************
To install, unzip and place 'EasyTransfer' folder into your 'C:\Users\{user name}\Documents\Arduino\libraries' folder or '{Arduino IDE path}\hardware\libraries" or {Arduino IDE path}\libraries" directory.
Restart the Arduino IDE, look for the Library under "Sketch" -> "Import Library". You can also try the examples by finding them
under "File" -> "Examples" -> "EasyTransfer".
All uses of the library are in the example sketchs.
*******************************************************************
Library now has two versions, one for regular hardware Serial, one for use with the NewSoftSerial library
making any Arduino pin capable of transfering data back and forth easily.
See the examples to find out how to use the library.

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,84 @@
/*This is an example of the EasyTransfer Library 2way communications.
The sketch is for the Arduino with a potentiometer attached to analog pin 0.
This other Arduino has the servo attached to pin 9.
Both have a putton attached to pin 12 and output a status using the LED on pin 13.
The idea is each arduino will read the status of the button attached to it, and send it
to the other Arduino, which will toggle it's LED based on the others button. The button
should connect pin 12 to ground when pushed.
And the Arduino with the potentiometer will send it's value to the one with the servo.
The servo will move to the position based on the potentiometer.
*/
#include <EasyTransfer.h>
//create two objects
EasyTransfer ETin, ETout;
struct RECEIVE_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t buttonstate;
};
struct SEND_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t buttonstate;
int16_t servoval;
};
//give a name to the group of data
RECEIVE_DATA_STRUCTURE rxdata;
SEND_DATA_STRUCTURE txdata;
void setup(){
Serial.begin(9600);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ETin.begin(details(rxdata), &Serial);
ETout.begin(details(txdata), &Serial);
pinMode(13, OUTPUT);
//enable pull-up
pinMode(12, INPUT_PULLUP);
}
void loop(){
//first, lets read our potentiometer and button and store it in our data structure
txdata.servoval = analogRead(0);
if(!digitalRead(12))
txdata.buttonstate = HIGH;
else
txdata.buttonstate = LOW;
//then we will go ahead and send that data out
ETout.sendData();
//there's a loop here so that we run the recieve function more often then the
//transmit function. This is important due to the slight differences in
//the clock speed of different Arduinos. If we didn't do this, messages
//would build up in the buffer and appear to cause a delay.
for(int i=0; i<5; i++){
//remember, you could use an if() here to check for new data, this time it's not needed.
ETin.receiveData();
//set our LED on or off based on what we received from the other Arduino
digitalWrite(13, rxdata.buttonstate);
//delay
delay(10);
}
//delay for good measure
delay(10);
}

View File

@ -0,0 +1,89 @@
/*This is an example of the EasyTransfer Library 2way communications.
This sketch is for the Arduino with the servo attached to pin 9.
The other Arduino has a potentiometer attached to analog pin 0.
Both have a putton attached to pin 12 and output a status using the LED on pin 13.
The idea is each arduino will read the status of the button attached to it, and send it
to the other Arduino, which will toggle it's LED based on the others button. The button
should connect pin 12 to ground when pushed.
And the Arduino with the potentiometer will send it's value to the one with the servo.
The servo will move to the position based on the potentiometer.
*/
#include <Servo.h>
#include <EasyTransfer.h>
//create two objects
EasyTransfer ETin, ETout;
//create servo
Servo myservo;
struct RECEIVE_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t buttonstate;
int16_t servoval;
};
struct SEND_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t buttonstate;
};
//give a name to the group of data
RECEIVE_DATA_STRUCTURE rxdata;
SEND_DATA_STRUCTURE txdata;
void setup(){
Serial.begin(9600);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ETin.begin(details(rxdata), &Serial);
ETout.begin(details(txdata), &Serial);
pinMode(13, OUTPUT);
//enable pull-up
pinMode(12, INPUT_PULLUP);
myservo.attach(9);
}
void loop(){
//first, lets read our button and store it in our data structure
if(!digitalRead(12))
txdata.buttonstate = HIGH;
else
txdata.buttonstate = LOW;
//then we will go ahead and send that data out
ETout.sendData();
//there's a loop here so that we run the recieve function more often then the
//transmit function. This is important due to the slight differences in
//the clock speed of different Arduinos. If we didn't do this, messages
//would build up in the buffer and appear to cause a delay.
for(int i=0; i<5; i++){
//remember, you could use an if() here to check for new data, this time it's not needed.
ETin.receiveData();
//set our LED on or off based on what we received from the other Arduino
digitalWrite(13, rxdata.buttonstate);
//set our servo position based on what we received from the other Arduino
//we will also map the ADC value to a servo value
myservo.write(map(rxdata.servoval, 0, 1023, 0, 179));
//delay
delay(10);
}
//delay for good measure
delay(10);
}

View File

@ -0,0 +1,40 @@
#include <EasyTransfer.h>
//create object
EasyTransfer ET;
struct RECEIVE_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t blinks;
int16_t pause;
};
//give a name to the group of data
RECEIVE_DATA_STRUCTURE mydata;
void setup(){
Serial.begin(9600);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ET.begin(details(mydata), &Serial);
pinMode(13, OUTPUT);
}
void loop(){
//check and see if a data packet has come in.
if(ET.receiveData()){
//this is how you access the variables. [name of the group].[variable name]
//since we have data, we will blink it out.
for(int i = mydata.blinks; i>0; i--){
digitalWrite(13, HIGH);
delay(mydata.pause * 100);
digitalWrite(13, LOW);
delay(mydata.pause * 100);
}
}
//you should make this delay shorter then your transmit delay or else messages could be lost
delay(250);
}

View File

@ -0,0 +1,43 @@
#include <EasyTransfer.h>
//create object
EasyTransfer ET;
struct SEND_DATA_STRUCTURE{
//put your variable definitions here for the data you want to send
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t blinks;
int16_t pause;
};
//give a name to the group of data
SEND_DATA_STRUCTURE mydata;
void setup(){
Serial.begin(9600);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ET.begin(details(mydata), &Serial);
pinMode(13, OUTPUT);
randomSeed(analogRead(0));
}
void loop(){
//this is how you access the variables. [name of the group].[variable name]
mydata.blinks = random(5);
mydata.pause = random(5);
//send the data
ET.sendData();
//Just for fun, we will blink it out too
for(int i = mydata.blinks; i>0; i--){
digitalWrite(13, HIGH);
delay(mydata.pause * 100);
digitalWrite(13, LOW);
delay(mydata.pause * 100);
}
delay(5000);
}

View File

@ -0,0 +1,22 @@
#######################################
# Syntax Coloring Map EasyTransfer
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
EasyTransfer KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
sendData KEYWORD2
receiveData KEYWORD2
begin KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
details LITERAL1

17
platformio.ini Normal file
View File

@ -0,0 +1,17 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:HoodLoader2atmega16u2]
platform = atmelavr
framework = arduino
board = HoodLoader2atmega16u2
lib_deps = nicohood/HID-Project @ ^2.6.1
; build_flags = -DMAGIC_KEY_POS=RAMEND-1 -DUSB_EP_SIZE=16
; build_flags = -DUSB_VID=0x2341 -DUSB_PID=0x484C -DUSB_MANUFACTURER='Nico Hood' -DUSB_PRODUCT='HoodLoader2 16u2' -DMAGIC_KEY_POS=RAMEND-1 -DUSB_EP_SIZE=16

1
src Submodule

@ -0,0 +1 @@
Subproject commit 83457b3391d7d128a21a216133ab4d6dfb9986c8