Skip to content

Commit

Permalink
Merge pull request #80 from scottgchin/LED-Support
Browse files Browse the repository at this point in the history
Led support
  • Loading branch information
scottgchin authored Aug 22, 2018
2 parents 47a3573 + a75921c commit 4e59f01
Show file tree
Hide file tree
Showing 45 changed files with 782 additions and 16 deletions.
61 changes: 61 additions & 0 deletions doc/Hardware and Software Setup Instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* Outdoor power cable, 50ft plus
* Network router
* Laptop/tablet
* ws2812b LEDs

## Hardware Setup

Expand All @@ -44,6 +45,10 @@ Complete wiring connections between each Arduino and the Raspberry Pi.
Note: be sure all Receiver Nodes and the Raspberry Pi are tied to a common ground; if not, the i2c messages can be corrupted.
![system wiring](img/D5-i2c.png)

### WS2812b LED Support
The pins in the green box is what were already used by the timer. The pins in the red box is where you connect the signal and ground from the ws2812b LEDs. The LEDs will require a separate power source. See WS2812b LED support under Software Setup.
![led wiring](img/GPIO.jpg)

## Software Setup

### Receiver Nodes (Arduinos)
Expand Down Expand Up @@ -85,6 +90,17 @@ Install web server packages, open a terminal in '/home/pi/delta5_race_timer/src/
sudo pip install -r requirements.txt
```

Update i2c baud rate
```
sudo nano /boot/config.txt
```
add the following line:
```
dtparam=i2c_baudrate=75000
```
Save and exit the file with Ctrl-x


## Starting the System

The following instructions will start the Delta5 Race Timer web server on the raspberry pi allowing full control and configuration of the system to run races and save lap times.
Expand Down Expand Up @@ -128,3 +144,48 @@ sudo systemctl daemon-reload
sudo systemctl enable delta5.service
sudo reboot
```
### WS2812b LED Support
The ws2812b controls are provided by the following project:
/~https://github.com/jgarff/rpi_ws281x

Perform an update and install the dependencies:
```
sudo apt-get update
sudo apt-get install build-essential python-dev git scons swig
```

Clone the repository onto the Pi and initiate Scons:
```
sudo git clone /~https://github.com/jgarff/rpi_ws281x.git
cd rpi_ws281x
sudo scons
```

Install the Python library:
```
cd python
sudo python setup.py install
```

Modify the config.txt file
```
sudo nano /boot/config.txt
```
add the following to the config.txt file
```
core_freq=250
```
Configure the Raspberry Pi to enable SPI
```
sudo raspi-config
```
Select 5 Interfacing Options

Select P4 SPI

and enable SPI

Reboot the Raspberry Pi
```
sudo reboot
```
Binary file added doc/img/GPIO.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 27 additions & 12 deletions src/delta5node/delta5node.ino
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
// Node Setup -- Set the i2c address here
// Node 1 = 8, Node 2 = 10, Node 3 = 12, Node 4 = 14
// Node 5 = 16, Node 6 = 18, Node 7 = 20, Node 8 = 22
#define i2cSlaveAddress 8
#define i2cSlaveAddress 20

const int slaveSelectPin = 10; // Setup data pins for rx5808 comms
const int spiDataPin = 11;
Expand Down Expand Up @@ -99,6 +99,22 @@ uint8_t volatile ioBuffer[32]; // Data array for sending over i2c, up to 32 byte
int ioBufferSize = 0;
int ioBufferIndex = 0;

// Define vtx frequencies in mhz and their hex code for setting the rx5808 module
int vtxFreqTable[] = {
5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725, // Band A
5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866, // Band B
5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945, // Band E
5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880, // Band F
5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 // Band C / Raceband
};
uint16_t vtxHexTable[] = {
0x2A05, 0x299B, 0x2991, 0x2987, 0x291D, 0x2913, 0x2909, 0x289F, // Band A
0x2903, 0x290C, 0x2916, 0x291F, 0x2989, 0x2992, 0x299C, 0x2A05, // Band B
0x2895, 0x288B, 0x2881, 0x2817, 0x2A0F, 0x2A19, 0x2A83, 0x2A8D, // Band E
0x2906, 0x2910, 0x291A, 0x2984, 0x298E, 0x2998, 0x2A02, 0x2A0C, // Band F
0x281D, 0x288F, 0x2902, 0x2914, 0x2987, 0x2999, 0x2A0C, 0x2A1E // Band C / Raceband
};

// Defines for fast ADC reads
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
Expand Down Expand Up @@ -170,21 +186,20 @@ void SERIAL_ENABLE_HIGH() {
delayMicroseconds(100);
}

// Calculate rx5808 register hex value for given frequency in MHz
uint16_t freqMhzToRegVal(uint16_t freqInMhz) {
uint16_t tf, N, A;
tf = (freqInMhz - 479) / 2;
N = tf / 32;
A = tf % 32;
return (N<<7) + A;
}

// Set the frequency given on the rx5808 module
void setRxModule(int frequency) {
uint8_t i; // Used in the for loops

// Get the hex value to send to the rx module
uint16_t vtxHex = freqMhzToRegVal(frequency);
uint8_t index; // Find the index in the frequency lookup table
for (i = 0; i < sizeof(vtxFreqTable); i++) {
if (frequency == vtxFreqTable[i]) {
index = i;
break;
}
}

uint16_t vtxHex; // Get the hex value to send to the rx module
vtxHex = vtxHexTable[index];

// bit bash out 25 bits of data / Order: A0-3, !R/W, D0-D19 / A0=0, A1=0, A2=0, A3=1, RW=0, D0-19=0
SERIAL_ENABLE_HIGH();
Expand Down
130 changes: 130 additions & 0 deletions src/delta5server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,87 @@
PROGRAM_START = datetime.now()
RACE_START = datetime.now() # Updated on race start commands

# LED Code
import time
from neopixel import *

import signal
def signal_handler(signal, frame):
colorWipe(strip, Color(0,0,0))
sys.exit(0)

# LED strip configuration:
LED_COUNT = 150 # Number of LED pixels.
#LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!).
LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10 # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53
LED_STRIP = ws.WS2811_STRIP_GRB # Strip type and colour ordering

# LED one color ON/OFF
def onoff(strip, color):
for i in range(strip.numPixels()):
strip.setPixelColor(i, color)
strip.show()

def theaterChase(strip, color, wait_ms=50, iterations=5):
"""Movie theater light style chaser animation."""
for j in range(iterations):
for q in range(3):
for i in range(0, strip.numPixels(), 3):
strip.setPixelColor(i+q, color)
strip.show()
time.sleep(wait_ms/1000.0)
for i in range(0, strip.numPixels(), 3):
strip.setPixelColor(i+q, 0)

def wheel(pos):
"""Generate rainbow colors across 0-255 positions."""
if pos < 85:
return Color(pos * 3, 255 - pos * 3, 0)
elif pos < 170:
pos -= 85
return Color(255 - pos * 3, 0, pos * 3)
else:
pos -= 170
return Color(0, pos * 3, 255 - pos * 3)

def rainbow(strip, wait_ms=2, iterations=1):
"""Draw rainbow that fades across all pixels at once."""
for j in range(256*iterations):
for i in range(strip.numPixels()):
strip.setPixelColor(i, wheel((i+j) & 255))
strip.show()
time.sleep(wait_ms/1000.0)

def rainbowCycle(strip, wait_ms=2, iterations=1):
"""Draw rainbow that uniformly distributes itself across all pixels."""
for j in range(256*iterations):
for i in range(strip.numPixels()):
strip.setPixelColor(i, wheel((int(i * 256 / strip.numPixels()) + j) & 255))
strip.show()
time.sleep(wait_ms/1000.0)

def theaterChaseRainbow(strip, wait_ms=25):
"""Rainbow movie theater light style chaser animation."""
for j in range(256):
for q in range(3):
for i in range(0, strip.numPixels(), 3):
strip.setPixelColor(i+q, wheel((i+j) % 255))
strip.show()
time.sleep(wait_ms/1000.0)
for i in range(0, strip.numPixels(), 3):
strip.setPixelColor(i+q, 0)

# Create NeoPixel object with appropriate configuration.
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
# Intialize the library (must be called once before other functions).
strip.begin()


#
# Database Models
#
Expand Down Expand Up @@ -521,12 +602,16 @@ def on_start_race():
'''Starts the race and the timer counting up, no defined finish.'''
start_race()
SOCKET_IO.emit('start_timer') # Loop back to race page to start the timer counting up
time.sleep(1)
onoff(strip, Color(0,255,0)) #GREEN ON

@SOCKET_IO.on('start_race_2min')
def on_start_race_2min():
'''Starts the race with a two minute countdown clock.'''
start_race()
SOCKET_IO.emit('start_timer_2min') # Loop back to race page to start a 2 min countdown
time.sleep(1)
onoff(strip, Color(0,255,0)) #GREEN ON

def start_race():
'''Common race start events.'''
Expand All @@ -549,6 +634,7 @@ def on_race_status():
SOCKET_IO.emit('stop_timer') # Loop back to race page to start the timer counting up
server_log('Race stopped')
emit_race_status() # Race page, to set race button states
onoff(strip, Color(255,0,0)) #RED ON

@SOCKET_IO.on('save_laps')
def on_save_laps():
Expand Down Expand Up @@ -623,6 +709,34 @@ def on_simulate_lap(data):
server_log('Simulated lap: Node {0}'.format(node_index))
INTERFACE.intf_simulate_lap(node_index)

@SOCKET_IO.on('LED_solid')
def on_LED_solid(data):
'''LED Solid Color'''
led_red = data['red']
led_green = data['green']
led_blue = data['blue']
onoff(strip, Color(led_red,led_green,led_blue))

@SOCKET_IO.on('LED_chase')
def on_LED_chase(data):
'''LED Solid Color'''
led_red = data['red']
led_green = data['green']
led_blue = data['blue']
theaterChase(strip, Color(led_red,led_green,led_blue))

@SOCKET_IO.on('LED_RB')
def on_LED_RB():
rainbow(strip) #Rainbow

@SOCKET_IO.on('LED_RBCYCLE')
def on_LED_RBCYCLE():
rainbowCycle(strip) #Rainbow Cycle

@SOCKET_IO.on('LED_RBCHASE')
def on_LED_RBCHASE():
theaterChaseRainbow(strip) #Rainbow Chase

# Socket io emit functions

def emit_race_status():
Expand Down Expand Up @@ -871,6 +985,22 @@ def pass_record_callback(node, ms_since_lap):
emit_leaderboard() # Updates leaderboard
if lap_id > 0:
emit_phonetic_data(pilot_id, lap_id, lap_time) # Sends phonetic data to be spoken
if node.index==0:
theaterChase(strip, Color(0,0,255)) #BLUE theater chase
elif node.index==1:
theaterChase(strip, Color(255,50,0)) #ORANGE theater chase
elif node.index==2:
theaterChase(strip, Color(255,0,60)) #PINK theater chase
elif node.index==3:
theaterChase(strip, Color(150,0,255)) #PURPLE theater chase
elif node.index==4:
theaterChase(strip, Color(250,210,0)) #YELLOW theater chase
elif node.index==5:
theaterChase(strip, Color(0,255,255)) #CYAN theater chase
elif node.index==6:
theaterChase(strip, Color(0,255,0)) #GREEN theater chase
elif node.index==7:
theaterChase(strip, Color(255,0,0)) #RED theater chase

INTERFACE.pass_record_callback = pass_record_callback

Expand Down
Binary file added src/delta5server/static/image/LED-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-cyan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-orange.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-pink.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-purple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-chase-yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-cyan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-orange.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-pink.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-purple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-rainbow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/delta5server/static/image/LED-yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 4e59f01

Please sign in to comment.