|
|||||||
![]() |
Forum Index > Projects > LED Pegboard and Matrix Projects | ||
Peggy 2 and Touch Inputs |
|||
| | | Printable Version |
|
Anonymous: stg | ||||||||
|
Hi PHP Formatted Code // constants won't change. They're used here to // set pin numbers const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin // variables will change int buttonState = 0; // variable for reading the pushbutton status void setup() { // initialize the LED pin as an output pinMode(ledPin, OUTPUT); // initialize the pushbutton pin as an input pinMode(buttonPin, INPUT); } void loop(){ digitalWrite(buttonPin, HIGH); // read the state of the pushbutton value buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed. // if it is, the buttonState is HIGH if (buttonState == HIGH) { // turn LED on digitalWrite(ledPin, HIGH); } else { // turn LED off digitalWrite(ledPin, LOW); } }
PHP Formatted Code // constants won't change. They're used here to // set pin numbers: const int buttonPin = 2; // the number of the pushbutton pin // variables will change: int buttonState = 0; // variable for reading the pushbutton status #include <Peggy2.h> #include <math.h> #include <stdlib.h> #include <avr/pgmspace.h> Peggy2 frame1; // Make a frame buffer object, called frame1 const PROGMEM prog_uint32_t data1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672, 1360, 2728, 1360, 2728, 1360, 2728, 1360, 672, 0, 0, 0 }; void setup() { // initialize the pushbutton pin as an input: pinMode(buttonPin, INPUT); frame1.HardwareInit(); // Call this once to init the hardware. // (Only needed once, even if you've got lots of frames.) unsigned short y = 0; while (y < 25) { frame1.WriteRow( y, pgm_read_dword(&data1[y])); y++; } } void loop(){ digitalWrite(buttonPin, HIGH); // read the state of the pushbutton value: buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed. // if it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn LED on: frame1.RefreshAll(10); //Draw frame buffer 10 times delay(1000); } else { // turn LED off: frame1.Clear(); } } |
![]()
|
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
I have made progress, I now have the image displayed constantly and then when i press the wire on the capacitive touch sensor it dissappears ( the reverse of what i wanted ). PHP Formatted Code /*int touchSensorPin = 9; // this is the digital input pin for the touch sensor int touchSensor = 0; // this is a variable to hold the state of the touch sensor #include <Peggy2.h> #include <math.h> #include <stdlib.h> #include <avr/pgmspace.h> Peggy2 frame1; // Make a frame buffer object, called frame1 const PROGMEM prog_uint32_t data1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672, 1360, 2728, 1360, 2728, 1360, 2728, 1360, 672, 0, 0, 0 }; void setup() { frame1.HardwareInit(); // Call this once to init the hardware. // (Only needed once, even if you've got lots of frames.) unsigned short y = 0; while (y < 25) { frame1.WriteRow( y, pgm_read_dword(&data1[y])); y++; } pinMode(touchSensorPin, INPUT); // set the touch sensor pin as a digital input } void loop() { digitalWrite(touchSensorPin, HIGH); touchSensor = digitalRead(touchSensorPin); // read the touch sensor if (touchSensor == HIGH) { // if the touch sensor is sending 5 volts frame1.RefreshAll(1); //Draw frame buffer 10 times } } |
|
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
Sorted it, changed the if value to LOW and increased the frame buffer to 10000. |
|
||||||||
|
|||||||||
|
Windell | ||||||||
|
I'm glad that you got the touch sensor working-- neat hack!
One more thing now, the LEDS illuminated are quite dim and could do with being brighter... i'm on an AC power supply and i've maxed out the trim pots yet I know they can go brighter as when I upload via Arduino a row often comes on and flashes randomly...
You need to back up and understand how the Peggy 2 works. Please read through this post for the gory details. Windell H. Oskay drwho(at)evilmadscientist.com http://www.evilmadscientist.com/ |
![]() Evil Scientist ![]() Status: offline
Registered: 06/15/06 |
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
Cheers Windell, that's clarified a lot... |
|
||||||||
|
|||||||||
|
Windell | ||||||||
|
Other factors aside, you can probably also switch out the resistor with a 25 or 30 mA setpoint-- between that and drawing only 9 rows, you should be able to make the display about 3.5 X brighter. Windell H. Oskay drwho(at)evilmadscientist.com http://www.evilmadscientist.com/ |
![]() Evil Scientist ![]() Status: offline
Registered: 06/15/06 |
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
Cheers for the help Windell, I think I'd rather stick to the Arduino program rather than modifying the library - only because upon opening the Peggy2.h and Peggy2.cpp I'm in a little over my head, I'm open to any help or advice you can provide though. PHP Formatted Code void loop() {touchSensor = digitalRead(touchSensorPin); // read the touch sensor if (touchSensor == LOW) { // if the touch sensor is sending 5 volts frame1.RefreshAll(5000); //Draw frame buffer 10 times } }
PHP Formatted Code In function 'void loop()':error: 'class Peggy2' has no member named 'ShowRow'
|
|
||||||||
|
|||||||||
|
Windell | ||||||||
|
There is not an existing function "ShowRow," and the error you get is reminding you of that. Windell H. Oskay drwho(at)evilmadscientist.com http://www.evilmadscientist.com/ |
![]() Evil Scientist ![]() Status: offline
Registered: 06/15/06 |
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
I'd be willing to give it a go by all means Windell, failing that an updated library would be great! |
|
||||||||
|
|||||||||
|
Windell | ||||||||
|
Okay-- totally untested here -- PHP Formatted Code void Peggy2::ShowRow(uint8_t rowNum){ union mix_t { unsigned long atemp; unsigned char c[4]; } mix; if (rowNum < 25){ mix.atemp = buffer[rowNum]; SPI_TX(mix.c[3]); SPI_TX(mix.c[2]); SPI_TX(mix.c[1]); PORTD = 0; // Turn displays off SPI_TX(mix.c[0]); PORTB |= 2U; //Latch Pulse PORTB &= 253U; rowNum++; if (rowNum < 16) PORTD = rowNum; else PORTD = (rowNum - 15) << 4; } else { SPI_TX(0); SPI_TX(0); SPI_TX(0); SPI_TX(0); PORTD = 0; // Turn displays off PORTB |= 2; //Latch Pulse PORTB &= 253; } }
PHP Formatted Code // Turn on a single row, with full (non-multiplexed) intensity.// Use rowNum value of 25 to turn off the row. // Can be used for limited or manual multiplexing. void ShowRow(uint8_t rowNum);
Windell H. Oskay drwho(at)evilmadscientist.com http://www.evilmadscientist.com/ |
![]() Evil Scientist ![]() Status: offline
Registered: 06/15/06 |
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
Right, that appears to be working Windell, but I couldn't use the code generated from the Peggy Draw to create the circle I wanted, instead I've used GetPoint and done it manually: PHP Formatted Code #include <Peggy2.h> #include <math.h> #include <stdlib.h> #include <avr/pgmspace.h> Peggy2 frame1; // Make a frame buffer object, called frame1 void setup() { frame1.HardwareInit(); // Call this once to init the hardware. } void loop() { frame1.ShowRow(24); frame1.SetPoint(6,24); frame1.SetPoint(8,24); frame1.SetPoint(10,24); frame1.SetPoint(12,24); frame1.ShowRow(23); frame1.SetPoint(5,23); frame1.SetPoint(7,23); frame1.SetPoint(9,23); frame1.SetPoint(11,23); frame1.SetPoint(13,23); frame1.ShowRow(22); frame1.SetPoint(4,22); frame1.SetPoint(6,22); frame1.SetPoint(8,22); frame1.SetPoint(10,22); frame1.SetPoint(12,22); frame1.SetPoint(14,22); frame1.ShowRow(21); frame1.SetPoint(3,21); frame1.SetPoint(5,21); frame1.SetPoint(7,21); frame1.SetPoint(9,21); frame1.SetPoint(11,21); frame1.SetPoint(13,21); frame1.SetPoint(15,21); frame1.ShowRow(20); frame1.SetPoint(4,20); frame1.SetPoint(6,20); frame1.SetPoint(8,20); frame1.SetPoint(10,20); frame1.SetPoint(12,20); frame1.SetPoint(14,20); frame1.ShowRow(19); frame1.SetPoint(3,19); frame1.SetPoint(5,19); frame1.SetPoint(7,19); frame1.SetPoint(9,19); frame1.SetPoint(11,19); frame1.SetPoint(13,19); frame1.SetPoint(15,19); frame1.ShowRow(18); frame1.SetPoint(4,18); frame1.SetPoint(6,18); frame1.SetPoint(8,18); frame1.SetPoint(10,18); frame1.SetPoint(12,18); frame1.SetPoint(14,18); frame1.ShowRow(17); frame1.SetPoint(3,17); frame1.SetPoint(5,17); frame1.SetPoint(7,17); frame1.SetPoint(9,17); frame1.SetPoint(11,17); frame1.SetPoint(13,17); frame1.SetPoint(15,17); frame1.ShowRow(16); frame1.SetPoint(4,16); frame1.SetPoint(6,16); frame1.SetPoint(8,16); frame1.SetPoint(10,16); frame1.SetPoint(12,16); frame1.SetPoint(14,16); frame1.ShowRow(15); frame1.SetPoint(3,15); frame1.SetPoint(5,15); frame1.SetPoint(7,15); frame1.SetPoint(9,15); frame1.SetPoint(11,15); frame1.SetPoint(13,15); frame1.SetPoint(15,15); frame1.ShowRow(14); frame1.SetPoint(4,14); frame1.SetPoint(6,14); frame1.SetPoint(8,14); frame1.SetPoint(10,14); frame1.SetPoint(12,14); frame1.SetPoint(14,14); frame1.ShowRow(13); frame1.SetPoint(5,13); frame1.SetPoint(7,13); frame1.SetPoint(9,13); frame1.SetPoint(11,13); frame1.SetPoint(13,13); frame1.ShowRow(12); frame1.SetPoint(6,12); frame1.SetPoint(8,12); frame1.SetPoint(10,12); frame1.SetPoint(12,12); }
PHP Formatted Code int touchSensorPin = 9; // this is the digital input pin for the touch sensor int touchSensor = 0; // this is a variable to hold the state of the touch sensor #include <Peggy2.h> #include <math.h> #include <stdlib.h> #include <avr/pgmspace.h> Peggy2 frame1; // Make a frame buffer object, called frame1 void setup() { frame1.HardwareInit(); // Call this once to init the hardware. // (Only needed once, even if you've got lots of frames.) pinMode(touchSensorPin, INPUT); // set the touch sensor pin as a digital input } void loop() { touchSensor = digitalRead(touchSensorPin); // read the touch sensor if (touchSensor == LOW) { // if the touch sensor is sending 5 volts frame1.ShowRow(24); frame1.SetPoint(6,24); frame1.SetPoint(8,24); frame1.SetPoint(10,24); frame1.SetPoint(12,24); frame1.ShowRow(23); frame1.SetPoint(5,23); frame1.SetPoint(7,23); frame1.SetPoint(9,23); frame1.SetPoint(11,23); frame1.SetPoint(13,23); frame1.ShowRow(22); frame1.SetPoint(4,22); frame1.SetPoint(6,22); frame1.SetPoint(8,22); frame1.SetPoint(10,22); frame1.SetPoint(12,22); frame1.SetPoint(14,22); frame1.ShowRow(21); frame1.SetPoint(3,21); frame1.SetPoint(5,21); frame1.SetPoint(7,21); frame1.SetPoint(9,21); frame1.SetPoint(11,21); frame1.SetPoint(13,21); frame1.SetPoint(15,21); frame1.ShowRow(20); frame1.SetPoint(4,20); frame1.SetPoint(6,20); frame1.SetPoint(8,20); frame1.SetPoint(10,20); frame1.SetPoint(12,20); frame1.SetPoint(14,20); frame1.ShowRow(19); frame1.SetPoint(3,19); frame1.SetPoint(5,19); frame1.SetPoint(7,19); frame1.SetPoint(9,19); frame1.SetPoint(11,19); frame1.SetPoint(13,19); frame1.SetPoint(15,19); frame1.ShowRow(18); frame1.SetPoint(4,18); frame1.SetPoint(6,18); frame1.SetPoint(8,18); frame1.SetPoint(10,18); frame1.SetPoint(12,18); frame1.SetPoint(14,18); frame1.ShowRow(17); frame1.SetPoint(3,17); frame1.SetPoint(5,17); frame1.SetPoint(7,17); frame1.SetPoint(9,17); frame1.SetPoint(11,17); frame1.SetPoint(13,17); frame1.SetPoint(15,17); frame1.ShowRow(16); frame1.SetPoint(4,16); frame1.SetPoint(6,16); frame1.SetPoint(8,16); frame1.SetPoint(10,16); frame1.SetPoint(12,16); frame1.SetPoint(14,16); frame1.ShowRow(15); frame1.SetPoint(3,15); frame1.SetPoint(5,15); frame1.SetPoint(7,15); frame1.SetPoint(9,15); frame1.SetPoint(11,15); frame1.SetPoint(13,15); frame1.SetPoint(15,15); frame1.ShowRow(14); frame1.SetPoint(4,14); frame1.SetPoint(6,14); frame1.SetPoint(8,14); frame1.SetPoint(10,14); frame1.SetPoint(12,14); frame1.SetPoint(14,14); frame1.ShowRow(13); frame1.SetPoint(5,13); frame1.SetPoint(7,13); frame1.SetPoint(9,13); frame1.SetPoint(11,13); frame1.SetPoint(13,13); frame1.ShowRow(12); frame1.SetPoint(6,12); frame1.SetPoint(8,12); frame1.SetPoint(10,12); frame1.SetPoint(12,12); } }
|
|
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
Sorted it... PHP Formatted Code if (touchSensor == LOW) { // if the touch sensor is sending 5 voltsvar = 0; while(var < 5000){
PHP Formatted Code var++;}
PHP Formatted Code }frame1.ShowRow(0);
|
|
||||||||
|
|||||||||
|
Windell | ||||||||
|
You may need to re-read that article Windell H. Oskay drwho(at)evilmadscientist.com http://www.evilmadscientist.com/ |
![]() Evil Scientist ![]() Status: offline
Registered: 06/15/06 |
||||||||
|
|||||||||
|
Anonymous: stg | ||||||||
|
Right, I've got it working so thanks Windell for the code! PHP Formatted Code int touchSensorPin = 9; // this is the digital input pin for the touch sensor int touchSensor = 0; // this is a variable to hold the state of the touch sensor int var = 0; #include <Peggy2.h> #include <math.h> #include <stdlib.h> #include <avr/pgmspace.h> Peggy2 frame1; // Make a frame buffer object, called frame1 void setup() { frame1.HardwareInit(); // Call this once to init the hardware. // (Only needed once, even if you've got lots of frames.) pinMode(touchSensorPin, INPUT); // set the touch sensor pin as a digital input } void loop() { frame1.ShowRow(25); // turn off LEDs before we start changing the array touchSensor = digitalRead(touchSensorPin); // read the touch sensor if (touchSensor == LOW) { // if the touch sensor is sending 5 volts var = 0; while(var < 500){ frame1.SetPoint(6,24); frame1.SetPoint(8,24); frame1.SetPoint(10,24); frame1.SetPoint(12,24); frame1.SetPoint(5,23); frame1.SetPoint(7,23); frame1.SetPoint(9,23); frame1.SetPoint(11,23); frame1.SetPoint(13,23); frame1.SetPoint(4,22); frame1.SetPoint(6,22); frame1.SetPoint(8,22); frame1.SetPoint(10,22); frame1.SetPoint(12,22); frame1.SetPoint(14,22); frame1.SetPoint(3,21); frame1.SetPoint(5,21); frame1.SetPoint(7,21); frame1.SetPoint(9,21); frame1.SetPoint(11,21); frame1.SetPoint(13,21); frame1.SetPoint(15,21); frame1.SetPoint(4,20); frame1.SetPoint(6,20); frame1.SetPoint(8,20); frame1.SetPoint(10,20); frame1.SetPoint(12,20); frame1.SetPoint(14,20); frame1.SetPoint(3,19); frame1.SetPoint(5,19); frame1.SetPoint(7,19); frame1.SetPoint(9,19); frame1.SetPoint(11,19); frame1.SetPoint(13,19); frame1.SetPoint(15,19); frame1.SetPoint(4,18); frame1.SetPoint(6,18); frame1.SetPoint(8,18); frame1.SetPoint(10,18); frame1.SetPoint(12,18); frame1.SetPoint(14,18); frame1.SetPoint(3,17); frame1.SetPoint(5,17); frame1.SetPoint(7,17); frame1.SetPoint(9,17); frame1.SetPoint(11,17); frame1.SetPoint(13,17); frame1.SetPoint(15,17); frame1.SetPoint(4,16); frame1.SetPoint(6,16); frame1.SetPoint(8,16); frame1.SetPoint(10,16); frame1.SetPoint(12,16); frame1.SetPoint(14,16); frame1.SetPoint(3,15); frame1.SetPoint(5,15); frame1.SetPoint(7,15); frame1.SetPoint(9,15); frame1.SetPoint(11,15); frame1.SetPoint(13,15); frame1.SetPoint(15,15); frame1.SetPoint(4,14); frame1.SetPoint(6,14); frame1.SetPoint(8,14); frame1.SetPoint(10,14); frame1.SetPoint(12,14); frame1.SetPoint(14,14); frame1.SetPoint(5,13); frame1.SetPoint(7,13); frame1.SetPoint(9,13); frame1.SetPoint(11,13); frame1.SetPoint(13,13); frame1.SetPoint(6,12); frame1.SetPoint(8,12); frame1.SetPoint(10,12); frame1.SetPoint(12,12); byte j = 12; while (j < 25){ frame1.ShowRow(j); delay(0.5); // delays by 2 ms! j++;} var++; } } }
PHP Formatted Code int touchSensorPin = 9; // this is the digital input pin for the touch sensor PB1 int touchSensor = 0; // this is a variable to hold the state of the touch sensor int touchSensorPin2 = 10; // this is the digital input pin for the touch sensor PB2 int touchSensor2 = 0; // this is a variable to hold the state of the touch sensor int var = 0; // this is for the delay in the LEDs being on int var2 = 0; // this is for the delay in the LEDs being on #include <Peggy2.h> #include <math.h> #include <stdlib.h> #include <avr/pgmspace.h> Peggy2 frame1; // Make a frame buffer object, called frame1 Peggy2 frame2; // Make a frame buffer object, called frame2 void setup() { frame1.HardwareInit(); // Call this once to init the hardware. // (Only needed once, even if you've got lots of frames.) pinMode(touchSensorPin, INPUT); // set the touch sensor pin as a digital input pinMode(touchSensorPin2, INPUT); // set the touch sensor pin as a digital input } void loop() { frame1.ShowRow(25); // turn off LEDs before we start changing the array touchSensor = digitalRead(touchSensorPin); // read the touch sensor at PB1 touchSensor2 = digitalRead(touchSensorPin2); // read the touch sensor at PB2 if (touchSensor == LOW) { // if the touch sensor is being touched var = 0; // set var as 0 (begin timing) while(var < 500){ frame1.SetPoint(6,24); //these are coordinates to be illuminated on the LED matrix frame1.SetPoint(8,24); frame1.SetPoint(10,24); frame1.SetPoint(12,24); frame1.SetPoint(5,23); frame1.SetPoint(7,23); frame1.SetPoint(9,23); frame1.SetPoint(11,23); frame1.SetPoint(13,23); frame1.SetPoint(4,22); frame1.SetPoint(6,22); frame1.SetPoint(8,22); frame1.SetPoint(10,22); frame1.SetPoint(12,22); frame1.SetPoint(14,22); frame1.SetPoint(3,21); frame1.SetPoint(5,21); frame1.SetPoint(7,21); frame1.SetPoint(9,21); frame1.SetPoint(11,21); frame1.SetPoint(13,21); frame1.SetPoint(15,21); frame1.SetPoint(4,20); frame1.SetPoint(6,20); frame1.SetPoint(8,20); frame1.SetPoint(10,20); frame1.SetPoint(12,20); frame1.SetPoint(14,20); frame1.SetPoint(3,19); frame1.SetPoint(5,19); frame1.SetPoint(7,19); frame1.SetPoint(9,19); frame1.SetPoint(11,19); frame1.SetPoint(13,19); frame1.SetPoint(15,19); frame1.SetPoint(4,18); frame1.SetPoint(6,18); frame1.SetPoint(8,18); frame1.SetPoint(10,18); frame1.SetPoint(12,18); frame1.SetPoint(14,18); frame1.SetPoint(3,17); frame1.SetPoint(5,17); frame1.SetPoint(7,17); frame1.SetPoint(9,17); frame1.SetPoint(11,17); frame1.SetPoint(13,17); frame1.SetPoint(15,17); frame1.SetPoint(4,16); frame1.SetPoint(6,16); frame1.SetPoint(8,16); frame1.SetPoint(10,16); frame1.SetPoint(12,16); frame1.SetPoint(14,16); frame1.SetPoint(3,15); frame1.SetPoint(5,15); frame1.SetPoint(7,15); frame1.SetPoint(9,15); frame1.SetPoint(11,15); frame1.SetPoint(13,15); frame1.SetPoint(15,15); frame1.SetPoint(4,14); frame1.SetPoint(6,14); frame1.SetPoint(8,14); frame1.SetPoint(10,14); frame1.SetPoint(12,14); frame1.SetPoint(14,14); frame1.SetPoint(5,13); frame1.SetPoint(7,13); frame1.SetPoint(9,13); frame1.SetPoint(11,13); frame1.SetPoint(13,13); frame1.SetPoint(6,12); frame1.SetPoint(8,12); frame1.SetPoint(10,12); frame1.SetPoint(12,12); byte j = 12; // this ensures that only the rows specified are multiplexed, increasing brightness - in this case row 12 and above while (j < 25){ frame1.ShowRow(j); delay(0.5); // delays by 2 ms! j++;} var++; // add 1 on to the var and repeat until the value at the top is reached } } if (touchSensor2 == LOW) { var2 = 0; while(var2 < 500){ frame2.SetPoint(6,24); frame2.SetPoint(8,24); frame2.SetPoint(10,24); frame2.SetPoint(5,23); frame2.SetPoint(7,23); frame2.SetPoint(9,23); frame2.SetPoint(11,23); frame2.SetPoint(4,22); frame2.SetPoint(6,22); frame2.SetPoint(8,22); frame2.SetPoint(10,22); frame2.SetPoint(12,22); frame2.SetPoint(5,21); frame2.SetPoint(7,21); frame2.SetPoint(9,21); frame2.SetPoint(11,21); frame2.SetPoint(4,20); frame2.SetPoint(6,20); frame2.SetPoint(8,20); frame2.SetPoint(10,20); frame2.SetPoint(12,20); frame2.SetPoint(5,19); frame2.SetPoint(7,19); frame2.SetPoint(9,19); frame2.SetPoint(11,19); frame2.SetPoint(4,18); frame2.SetPoint(6,18); frame2.SetPoint(8,18); frame2.SetPoint(10,18); frame2.SetPoint(12,18); frame2.SetPoint(5,17); frame2.SetPoint(7,17); frame2.SetPoint(9,17); frame2.SetPoint(11,17); frame2.SetPoint(6,16); frame2.SetPoint(8,16); frame2.SetPoint(10,16); byte k = 16; while (k < 25){ frame2.ShowRow(k); delay(0.5); k++;} var2++; } } } |
|
||||||||
|
|||||||||
|
Windell | ||||||||
|
Try debugging the sensor code separately from the display code. Windell H. Oskay drwho(at)evilmadscientist.com http://www.evilmadscientist.com/ |
![]() Evil Scientist ![]() Status: offline
Registered: 06/15/06 |
||||||||
|
|||||||||
|
|
| All times are PDT. The time is now 02:25 AM. |
|
|
Octolively
Interactive LED kits
Meggy Jr RGB
LED matrix game
development kit.
Business-card sized
AVR target boards
Peggy 2
LED Pegboard kits