|
|
Line 423: |
Line 423: |
| Direct soldering to 8-way Alarm cable x 2 + 1 GND wire and mounted in Spencer's tiny 3D printed case. Replaces a USB dancemat controller that I was never 100% happy with! | | Direct soldering to 8-way Alarm cable x 2 + 1 GND wire and mounted in Spencer's tiny 3D printed case. Replaces a USB dancemat controller that I was never 100% happy with! |
| | | |
− | <gallery widths=300px heights=300px> | + | <gallery widths=300px heights=300px> |
| File:Promicro-wiring-direct.png|Direct soldering | | File:Promicro-wiring-direct.png|Direct soldering |
| File:Promicro-halfwired.png|Half-wired | | File:Promicro-halfwired.png|Half-wired |
Line 430: |
Line 430: |
| File:Promicro-replacing-this.png|Replacing this mess | | File:Promicro-replacing-this.png|Replacing this mess |
| </gallery> | | </gallery> |
| + | |
| + | === Large-style Pro Micro board === |
| + | |
| + | I have taken delivery of another 10 boards at a cost of £2.35 each (including postage). These are the same technical specification and functionally equivalent however are slightly larger on a PCB of 23 x 40 mm with a Mini-USB socket rather than a Micro-USB socket. |
Revision as of 09:25, 4 September 2015
Many hackers wish to produce a USB device that presents itself as a HID joypad, keyboard, or mouse to a PC or Pi to provide interesting interactions and I/O opportunities in a "standardised" manner. The Arduino Micro and more recently the Leonardo use a micro with an inbuilt USB peripheral device that can be repurposed directly. Previously the Arduino boards used a second small micro or dedicated USB chip (essentially another micro) to perform the USB-serial task but the cost of this additional device was high (often more than the micro itself) and that essential USB device feature soon found itself integrated into a number of Atmel chips. This was an opportunity for the Arduino project to divorce itself from a massive dependence on FTDI (in good time for #FTDIGATE !!) and for hackers to get involved with the delights of the at90usb82, atmega16u2, etc. as secondary processors for USB comms.
Time rolls on and the excitement of the brilliant but non-open Minimus project dies down to find a number of crazy-cheap options where the USB chip is the main chip. The Atmega32U4 can be found on the Arduino Micro (currently for about £20) but also on the wonderful Teensy 2.0 and some really cheap little "Pro Micro" boards from China that at £4 each are cheaper than buying just the chip from here in the UK (in reasonable quantities). Myself (Michael E) and Spencer have ordered some of these bonkers-cheap units for initial testing and evaluation. They would appear to be clones of the Sparkfun Pro Micro https://www.sparkfun.com/products/12640
Info Dump
Initial Works for DELIVERY 1
- board inspection: -
- what is included other than the MCU and a 16MHz crystal?
- what is missing other than the ICSP header?
- programming the board as an Arduino with Arduino IDE
- programming with dfu-programmer and avr-gcc, avr-libc, etc.
- what bootloader is provided? The Teensy 2.0 HALFKAY?
Chip markings (from ebay photos until we receive our first delivery)
ATMEL
MEGA32U4
-MU
1448E TH
A2N7XA
Initial risks and mitigations: -
- not a real ATMEL chip or bad batch/revision
- closer inspection of chip markings and initial firmware tests
- check JTAG IDs and Device Identification Register (26.3.2 in datasheet)
- bad oscillator circuitry or configuration
- pinout mapping for Arduino/teensy/Micro
J1 |USBu|
TX0 RAW
RX1 GND
GND RST
GND VCC
2 A3
3 A2
4 A1
5 A0
6 15
7 14
8 16
9 10
+----------------+
Michael's USB-HID Work
Origins: -
New project - very similar...
Test for ProMicro with 8 inputs and keyboard output: -
1 static uint8_t bprev;
2 static uint8_t bnew;
3
4 const int pmin = 2;
5 const int pmax = 9;
6
7
8 void setup() {
9
10 for(int i = pmin; i <= pmax; i++){
11 pinMode(i, INPUT_PULLUP);
12 }
13 Serial.begin(9600);
14 Keyboard.begin();
15 bprev = bnew = btn_read();
16 }
17
18 void loop() {
19 bnew = btn_read();
20 if(bnew != bprev){
21 Keyboard.write('z');
22 Serial.print("btns = ");
23 Serial.println(bnew, HEX);
24 bprev = bnew;
25 }
26 // force change with any serial input
27 if(Serial.available() > 0) {
28 int b = Serial.read();
29 Serial.print("RX: ");
30 Serial.println(b, DEC);
31 bprev = ~bprev;
32 }
33 }
34
35 uint8_t btn_read(void) {
36 uint8_t v = 0;
37 for(int i = pmin; i <= pmax; i++){
38 bitWrite(v, i-pmin, digitalRead(i));
39 }
40 return v;
41 }
Test for ProMicro with 8 inputs, debounce, multitasking and serial output: -
1 /* Pro Micro Test Code
2 by: Nathan Seidle
3 modified by: Jim Lindblom
4 SparkFun Electronics
5 date: September 16, 2013
6 license: Public Domain - please use this code however you'd like.
7 It's provided as a learning tool.
8
9 This code is provided to show how to control the SparkFun
10 ProMicro's TX and RX LEDs within a sketch. It also serves
11 to explain the difference between Serial.print() and
12 Serial1.print().
13
14 modified by: Michael Erskine
15 Nottingham Hackspace
16 date: August 28th, 2015
17 Added digital inputs from 2-9 with debounce and simple multitasking
18
19 */
20
21 int RXLED = 17; // The RX LED has a defined Arduino pin
22 // The TX LED was not so lucky, we'll need to use pre-defined
23 // macros (TXLED1, TXLED0) to control that.
24 // (We could use the same macros for the RX LED too -- RXLED1,
25 // and RXLED0.)
26
27 void setup()
28 {
29 pinMode(RXLED, OUTPUT); // Set RX LED as an output
30 // TX LED is set as an output behind the scenes
31
32 Serial.begin(9600); //This pipes to the serial monitor
33 Serial1.begin(9600); //This is the UART, pipes to sensors attached to board
34
35 inputs_setup();
36 }
37
38 const int da_start = 2;
39 const int da_num = 4;
40 static uint8_t da_inputs = 0;
41
42 void inputs_setup(void) {
43 for(int i = 0; i < da_num; i++) {
44 pinMode(da_start + i, INPUT_PULLUP);
45 }
46 da_inputs = inputs_read();
47 }
48
49 uint8_t inputs_read(void)
50 {
51 uint8_t da_samp = 0;
52 for(int i = 0; i < da_num; i++) {
53 bitWrite(da_samp, i, (digitalRead(da_start + i) ? 0 : 1));
54 }
55 return da_samp;
56 }
57
58 void loop()
59 {
60 task_led_toggle();
61 task_inputs();
62 task_serial_read();
63 }
64
65 void task_inputs(void)
66 {
67 static uint32_t last;
68 uint32_t now = millis();
69 if(now - last > 5) {
70 last = now;
71 uint8_t da_samp = inputs_read();
72 uint8_t toggle;
73 da_samp = debounce(da_samp, &toggle);
74 if(da_samp != da_inputs) {
75 da_inputs = da_samp;
76 Serial.print("Inputs: ");
77 Serial.println(da_inputs, BIN);
78 }
79 }
80 }
81
82 void task_led_toggle(void)
83 {
84 static uint32_t last;
85 static bool on = false;
86 uint32_t now = millis();
87 if(now - last > 1000) {
88 last = now;
89 // Serial.println("Hello world"); // Print "Hello World" to the Serial Monitor
90 // Serial1.println("Hello!"); // Print "Hello!" over hardware UART
91 if(on){
92 digitalWrite(RXLED, LOW); // set the LED on
93 TXLED0; //TX LED is not tied to a normally controlled pin
94 } else {
95 digitalWrite(RXLED, HIGH); // set the LED off
96 TXLED1;
97 }
98 on = !on;
99 }
100 }
101
102 void task_serial_read(void) {
103 // TODO
104
105 }
106
107 /*
108 * http://www.compuphase.com/electronics/debouncing.htm
109 */
110 unsigned char debounce(unsigned char sample, unsigned char *toggle)
111 {
112 static unsigned char state, cnt0, cnt1;
113 unsigned char delta;
114
115 delta = sample ^ state;
116 cnt1 = (cnt1 ^ cnt0) & delta;
117 cnt0 = ~cnt0 & delta;
118
119 *toggle = delta & ~(cnt0 | cnt1);
120 state ^= *toggle;
121
122 return state;
123 }
Test for ProMicro with USB HID joystick, 8 inputs, debounce, multitasking and serial output (NB: needs mods to Arduino core USBAPI.h and HID.cpp in \arduino-1.6.5-r2\hardware\arduino\avr\cores\arduino): -
1 /* Pro Micro Test Code
2 by: Nathan Seidle
3 modified by: Jim Lindblom
4 SparkFun Electronics
5 date: September 16, 2013
6 license: Public Domain - please use this code however you'd like.
7 It's provided as a learning tool.
8
9 This code is provided to show how to control the SparkFun
10 ProMicro's TX and RX LEDs within a sketch. It also serves
11 to explain the difference between Serial.print() and
12 Serial1.print().
13
14 modified by: Michael Erskine
15 Nottingham Hackspace
16 date: August 28th, 2015
17 Added digital inputs from 2-9 with debounce and simple multitasking
18
19 */
20
21 int RXLED = 17; // The RX LED has a defined Arduino pin
22 // The TX LED was not so lucky, we'll need to use pre-defined
23 // macros (TXLED1, TXLED0) to control that.
24 // (We could use the same macros for the RX LED too -- RXLED1,
25 // and RXLED0.)
26
27 // Joystick State
28 static JoyState_t JoySt;
29
30 void setup()
31 {
32 pinMode(RXLED, OUTPUT); // Set RX LED as an output
33 // TX LED is set as an output behind the scenes
34
35 Serial.begin(9600); //This pipes to the serial monitor
36 Serial1.begin(9600); //This is the UART, pipes to sensors attached to board
37
38 JoySt.XAxis = 127;
39 JoySt.YAxis = 127;
40 JoySt.Buttons = 0;
41
42 inputs_setup();
43 }
44
45 const int da_start = 2;
46 const int da_num = 4;
47 static uint8_t da_inputs = 0;
48
49 void inputs_setup(void) {
50 for(int i = 0; i < da_num; i++) {
51 pinMode(da_start + i, INPUT_PULLUP);
52 }
53 da_inputs = inputs_read();
54 }
55
56 uint8_t inputs_read(void)
57 {
58 uint8_t da_samp = 0;
59 for(int i = 0; i < da_num; i++) {
60 bitWrite(da_samp, i, (digitalRead(da_start + i) ? 0 : 1));
61 }
62 return da_samp;
63 }
64
65 void loop()
66 {
67 task_led_toggle();
68 task_inputs();
69 task_serial_read();
70 }
71
72 void task_inputs(void)
73 {
74 static uint32_t last;
75 uint32_t now = millis();
76 if(now - last > 5) {
77 last = now;
78 uint8_t da_samp = inputs_read();
79 uint8_t toggle;
80 da_samp = debounce(da_samp, &toggle);
81 if(da_samp != da_inputs) {
82 da_inputs = da_samp;
83 //Serial.print("Inputs: ");
84 //Serial.println(da_inputs, BIN);
85 }
86
87 // Now do the USB HID magic...
88 // NB: every 5ms max
89 // JoySt.XAxis = 127 + N64Controller.GetStick_x();
90 // JoySt.YAxis = 127 + N64Controller.GetStick_y();
91 // map first two buttons to up and down for testing
92 if(da_samp & 0x01) // up
93 JoySt.XAxis = 0;
94 else if( da_samp & 0x02) // down
95 JoySt.XAxis = 255;
96 else
97 JoySt.XAxis = 127;
98 // leave Y centred for now
99 JoySt.YAxis = 127;
100 JoySt.Buttons = da_samp;
101 Joystick.setState(&JoySt);
102 }
103 }
104
105 void task_led_toggle(void)
106 {
107 static uint32_t last;
108 static bool on = false;
109 uint32_t now = millis();
110 if(now - last > 1000) {
111 last = now;
112 // Serial.println("Hello world"); // Print "Hello World" to the Serial Monitor
113 // Serial1.println("Hello!"); // Print "Hello!" over hardware UART
114 if(on){
115 digitalWrite(RXLED, LOW); // set the LED on
116 TXLED0; //TX LED is not tied to a normally controlled pin
117 } else {
118 digitalWrite(RXLED, HIGH); // set the LED off
119 TXLED1;
120 }
121 on = !on;
122 }
123 }
124
125 void task_serial_read(void) {
126 // TODO
127
128 }
129
130 /*
131 * http://www.compuphase.com/electronics/debouncing.htm
132 */
133 unsigned char debounce(unsigned char sample, unsigned char *toggle)
134 {
135 static unsigned char state, cnt0, cnt1;
136 unsigned char delta;
137
138 delta = sample ^ state;
139 cnt1 = (cnt1 ^ cnt0) & delta;
140 cnt0 = ~cnt0 & delta;
141
142 *toggle = delta & ~(cnt0 | cnt1);
143 state ^= *toggle;
144
145 return state;
146 }
Success!!!!
I now have the holy grail of full Arduino IDE and APIs for with HID joypad on the Pro Micro clone - all working and tested. --Michael Erskine (talk) 15:38, 28 August 2015 (UTC)
Joypad code now on Github
The USB HID Joypad code is now in Github.
https://github.com/msemtd/promicro-joypad
You will need to edit some of the USB HID files in the Arduino core of 1.6.5 (ask for details). In time I should probably create a completely separate board profile but that's a lot of work! --Michael Erskine (talk) 09:42, 1 September 2015 (UTC)
Wired into Defender Control Panel
Direct soldering to 8-way Alarm cable x 2 + 1 GND wire and mounted in Spencer's tiny 3D printed case. Replaces a USB dancemat controller that I was never 100% happy with!
Large-style Pro Micro board
I have taken delivery of another 10 boards at a cost of £2.35 each (including postage). These are the same technical specification and functionally equivalent however are slightly larger on a PCB of 23 x 40 mm with a Mini-USB socket rather than a Micro-USB socket.