Skip to content

Commit

Permalink
Merge pull request #1 from xtruan/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
xtruan authored Jul 19, 2018
2 parents b870aa1 + 9619cad commit 0a4bdd7
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 0 deletions.
132 changes: 132 additions & 0 deletions arduino/actuator/actuator.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <MeccaBrain.h>
#include <Wire.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

// set I2C address
const int I2C_ADDR = 0x8;

// configure pin addresses
const int LED_PIN = LED_BUILTIN;
const int MECC_LED_PIN = 3;

// initialize MeccaBrain
MeccaBrain meccLedChain(MECC_LED_PIN);
const int MECC_COMM_LOOPS = 20;

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);

// initialize Meccano LED pin as an output
pinMode(MECC_LED_PIN, OUTPUT);

Wire.begin(I2C_ADDR);

#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
// deactivate internal pull-ups for twi
// as per note from atmega8 manual pg167
cbi(PORTC, 4);
cbi(PORTC, 5);
#else
// deactivate internal pull-ups for twi
// as per note from atmega128 manual pg204
cbi(PORTD, 0);
cbi(PORTD, 1);
#endif

Wire.onReceive(receiveEvent); // register event handler

Serial.begin(9600);

// discover Meccano modules
for (int i = 0; i < MECC_COMM_LOOPS; i++)
{
meccLedChain.communicate();
}

delay(2000);
}

// the loop function runs over and over again forever
void loop() {
// NOP
}

// action received for Meccano LED
void actionMeccLed(int setting) {
byte red, green, blue;
byte fadeTime = 0x0;
if (setting == 0) {
red = 0x0; green = 0x0; blue = 0x0;
} else if (setting == 1) {
red = 0x7; green = 0x0; blue = 0x0;
} else if (setting == 2) {
red = 0x0; green = 0x7; blue = 0x0;
} else if (setting == 3) {
red = 0x0; green = 0x0; blue = 0x7;
} else if (setting == 4) {
red = 0x7; green = 0x7; blue = 0x0;
} else if (setting == 5) {
red = 0x0; green = 0x7; blue = 0x7;
} else if (setting == 6) {
red = 0x7; green = 0x0; blue = 0x7;
} else if (setting == 7) {
red = 0x7; green = 0x7; blue = 0x7;
} else {
red = 0x0; green = 0x0; blue = 0x0;
}
setMeccLedColor(red, green, blue, fadeTime);
}

// set the color of Meccano LED.
// red, green and blue are from 0 to 7 (0 - no color, 7 - max color)
// fadeTime is from 0 to 7 and means the speed of color change (0 - immediate change, 7 - longest change)
// example: setMeccLedColor(7, 0, 0, 0) means change color to red immediately
void setMeccLedColor(byte red, byte green, byte blue, byte fadeTime)
{
meccLedChain.setLEDColor(red, green, blue, fadeTime);
for (int i = 0; i < MECC_COMM_LOOPS; i++)
{
meccLedChain.communicate();
}
}

// action received for test (internal Ardino) LED
void actionTestLed(char setting) {
if (setting == 0) {
digitalWrite(LED_PIN, 0);
} else {
digitalWrite(LED_PIN, 1);
}
}

// process received event
void processEvent(char type, char id, char setting) {
if (type == 'L') {
actionTestLed(setting);
} else if (type == 'M') {
actionMeccLed(setting);
} else if (type == 'S') {
// NOP
}
}

// executes when data is received from I2C master
// registered as an event handler; see setup()
void receiveEvent(int howMany) {
while (Wire.available()) { // loop through all but the last
if (Wire.available() == 3) {
char type = Wire.read(); // receive byte as a character
char id = Wire.read(); // receive byte as a character
char setting = Wire.read(); // receive byte as a character
processEvent(type, id, setting);
} else {
char c = Wire.read(); // receive byte as a character
}
}
}
63 changes: 63 additions & 0 deletions raspi/control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from collections import deque
import csv
import argparse
import time

import utils.transform as transform
import utils.i2c as i2c
from objects.anim_action import AnimAction

COL_TIME_STR = 0
COL_DEVICE_TYPE = 1
COL_DEVICE_ID = 2
COL_SETTING = 3

anim_actions = deque([])

def read_anim_csv(filename, delimiter=',', quotechar='"'):
csv_file = open(filename, 'r')
csv_reader = csv.reader(csv_file, delimiter=delimiter, quotechar=quotechar)

for row in csv_reader:
time_str = str(row[COL_TIME_STR])
time_sec = transform.time_convert(time_str)
device_type = str(row[COL_DEVICE_TYPE])
device_id = int(row[COL_DEVICE_ID])
setting = int(row[COL_SETTING])

action = AnimAction(time_str, time_sec, device_type, device_id, setting)
anim_actions.append(action)

csv_file.close()

def handle_anim():
start = time.time()
end = time.time()
while len(anim_actions) > 0:
if anim_actions[0].time_sec <= end - start:
handle_action(anim_actions.popleft())
time.sleep(0.001)
end = time.time()

def handle_action(action):
i2c.write_anim_i2c(action)
print(action)

def main():
parser = argparse.ArgumentParser(description="Animatronic Control Program")
parser.add_argument('-i', '--input', type=str, required=True)
args = parser.parse_args()

input_file = args.input
print('Input file: ' + input_file)
if '.csv' in input_file.lower():
print('Loading file...')
read_anim_csv(input_file)
print('Loaded!')
wait = input('Press enter to continue...')
handle_anim()
else:
raise Exception('Invalid file type')

if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions raspi/objects/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


12 changes: 12 additions & 0 deletions raspi/objects/anim_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

class AnimAction:
def __init__(self, time_str, time_sec, device_type, device_id, setting):
self.time_str = time_str
self.time_sec = time_sec
self.device_type = device_type
self.device_id = device_id
self.setting = setting

def __str__(self):
return str(self.time_str) + '-' + str(self.device_type) + '-' + str(self.device_id) + '-' + str(self.setting)

13 changes: 13 additions & 0 deletions raspi/test.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
00:00:01.10,LED,1,1
00:00:01.20,LED,1,0
00:00:01.30,LED,1,1
00:00:01.40,LED,1,0
00:00:03.00,MLED,1,0
00:00:05.00,MLED,1,1
00:00:07.00,MLED,1,2
00:00:09.00,MLED,1,3
00:00:11.00,MLED,1,4
00:00:13.00,MLED,1,5
00:00:15.00,MLED,1,6
00:00:17.00,MLED,1,7
00:00:20.00,SVO,1,90
2 changes: 2 additions & 0 deletions raspi/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


15 changes: 15 additions & 0 deletions raspi/utils/i2c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from smbus import SMBus

from objects.anim_action import AnimAction

I2C_ADDR = 0x8 # bus address
I2C_BUS = SMBus(1) # indicates /dev/ic2-1



def write_anim_i2c(action):
data = [action.device_type.encode()[0], action.device_id, action.setting]
I2C_BUS.write_i2c_block_data(I2C_ADDR, 0x0, data)
#I2C_BUS.write_byte(I2C_ADDR, action.device_type.encode()[0])
#I2C_BUS.write_byte(I2C_ADDR, action.device_id)
#I2C_BUS.write_byte(I2C_ADDR, action.setting)
4 changes: 4 additions & 0 deletions raspi/utils/transform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

def time_convert(time_str):
time_list = time_str.split(':')
return float(int(time_list[0]) * 3600 + int(time_list[1]) * 60 + float(time_list[2]))

0 comments on commit 0a4bdd7

Please sign in to comment.