Lab_interaccio/2016/LASERS/Z_OSC/examples/Z_SimpleRecieve/BahiaFirmware.pde

450 lines
11 KiB
Plaintext
Raw Normal View History

2025-02-25 21:29:42 +01:00
/*
* BahiaFirmware.pde
*
* Copyright 2011 Carlos Jenkins <cjenkins@softwarelibrecr.org>
* Kevin Esquivel <kevinesquivel21@gmail.com>
* J Nathan Guillen A <aguzzi7@gmail.com>
*
* 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 2 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
/////////////////////////////
// INCLUDES
/////////////////////////////
/////////////////////////////
// DEFINITIONS
/////////////////////////////
/*
Board ID
*/
#define BAHIA_ID 1
/*
Address Bus pins
*/
#define ADDR_A 2
#define ADDR_B 3
#define ADDR_C 4
/*
Amount of non-multiplexes IOs
*/
#define PINS 14
/*
Amount of multiplexed pins and how many
*/
#define PINS_MULTI 6
#define PINS_MULTI_AMOUNT 8
/*
According to "Digi Connect ME and Wi-ME Hardware Reference" page 39
Data Rates (bps):
50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 14400,
19200, 28800, 38400, 57600, 115200, 230400, 460800 (Digi Connect ME 9210 only),
921600 (Digi Connect ME 9210 only)
*/
#define BAUD_RATE 9600
/*
OSC message size
*/
#define MESSAGE_SIZE 20
/*
Pin mode definitions
Digital Input
Digital Output
Analog Input
Analog Output (PWM)
*/
#define MODE_DI 0
#define MODE_DO 1
#define MODE_AI 2
#define MODE_AO 3
/////////////////////////////
// VARIABLES
/////////////////////////////
// Map bahia_pin with Arduino pins
const static uint8_t bahia_to_arduino[PINS] = {
A0, //X1
A1, //X2
A2, //X3
A3, //X4
A4, //X5
A5, //X6
13, //X7_0
12, //X7_1
11, //X7_2
9, //X7_3
5, //X7_4
6, //X7_5
7, //X7_6
8 //X7_7
};
// Hardware table definitions
const static boolean can_analog_input[PINS] = {
true, //X1
true, //X2
true, //X3
true, //X4
true, //X5
true, //X6
false, //X7_0
false, //X7_1
false, //X7_2
false, //X7_3
false, //X7_4
false, //X7_5
false, //X7_6
false //X7_7
};
const static boolean can_pwm_output[PINS] = {
false, //X1
false, //X2
false, //X3
false, //X4
false, //X5
false, //X6
false, //X7_0
false, //X7_1
true, //X7_2
true, //X7_3
true, //X7_4
true, //X7_5
false, //X7_6
false //X7_7
};
const static boolean is_multiplexed[PINS] = {
true, //X1
true, //X2
true, //X3
true, //X4
true, //X5
true, //X6
false, //X7_0
false, //X7_1
false, //X7_2
false, //X7_3
false, //X7_4
false, //X7_5
false, //X7_6
false //X7_7
};
static boolean read_enabled[PINS] = {
true, //X1 (Digital In)
true, //X2 (Digital In)
false, //X3
false, //X4
true, //X5 (Analog In)
true, //X6 (Analog In)
false, //X7_0
false, //X7_1
false, //X7_2
false, //X7_3
false, //X7_4
false, //X7_5
false, //X7_6
false //X7_7
};
static boolean read_enabled_multiplexed[PINS_MULTI][PINS_MULTI_AMOUNT] = {
{true , true , true , true , true , true , true , true }, // X1_
{true , true , true , true , true , true , true , true }, // X2_
{false, false, false, false, false, false, false, false}, // X3_
{false, false, false, false, false, false, false, false}, // X4_
{true , true , true , true , true , true , true , true }, // X5_
{true , true , true , true , true , true , true , true } // X6_
};
static byte pin_mode[PINS] = {
MODE_DI, //X1
MODE_DI, //X2
MODE_DO, //X3
MODE_DO, //X4
MODE_AI, //X5
MODE_AI, //X6
MODE_DO, //X7_0
MODE_DO, //X7_1
MODE_AO, //X7_2
MODE_AO, //X7_3
MODE_AO, //X7_4
MODE_AO, //X7_5
MODE_DO, //X7_6
MODE_DO //X7_7
};
static char incomming_message[MESSAGE_SIZE] = { // Message template
'/', 'a', 'r', 'd',
'/', B0,
'/', 'o', 'p',
'/', B0, '\0',
',', 'i', '\0', '\0',
B0, B0, B0, B0
};
static int incomming_value = 0;
/////////////////////////////
// MAIN FUNCTIONS
/////////////////////////////
// Arduino main setup function
void setup()
{
// Configure Hardware
for(byte i = 0; i < PINS; i++) {
if((pin_mode[i] == MODE_DI) || (pin_mode[i] == MODE_AI)) {
pinMode(bahia_to_arduino[i], INPUT);
} else {
pinMode(bahia_to_arduino[i], OUTPUT);
}
}
// Configure Serial port
Serial.begin(BAUD_RATE);
}
// Arduino main loop function
void loop()
{
// Check for incomming messages
checkIncomming();
// Now, stream values
for(byte i = 0; i < PINS; i++) {
if(read_enabled[i]) { // Read for that pin is enable
if(is_multiplexed[i]) { // Check if is multiplexed
// It is, so check if multiplexed channel is enabled to read
for(byte j = 0; j < PINS_MULTI_AMOUNT; j++) {
if(read_enabled_multiplexed[i][j]) {
read_and_broadcast(i, j);
}
}
} else { // We know it's a X7 pin
read_and_broadcast(i, 255);
}
}
}
}
/////////////////////////////
// HELPER FUNCTIONS
/////////////////////////////
// Check Incomming Messages
void checkIncomming() {
// Check for new configuration messages
if(Serial.available() >= MESSAGE_SIZE) {
// Get the message
for(byte i = 0; i < MESSAGE_SIZE; i++) {
incomming_message[i] = Serial.read();
}
// Check OSC Message
if(incomming_message[0] != '/') {
return;
}
// Check namespace
if(
(incomming_message[1] != 'a') ||
(incomming_message[2] != 'r') ||
(incomming_message[3] != 'd')
) {
return;
}
// Check id
if(incomming_message[5] != BAHIA_ID) {
return;
}
// Check instruction type and perform action
char instruction_type = incomming_message[7];
byte pin_n = incomming_message[10];
int argument = int(word(byte(incomming_message[18]), byte(incomming_message[19])));
switch(instruction_type) {
case 'w': // Write value
instructionWrite(pin_n, argument);
break;
case 'e': // Enable/disable sensor
instructionEnable(pin_n, argument == 0 ? true : false);
break;
case 'c': // Configure pin funtion
instructionConfigure(pin_n, argument);
break;
default:
return; // Unknown instruction, ignoring
}
}// If not enough bytes in buffer, then do nothing
}
// Perform a Write instruction
void instructionWrite(byte pin_n, int value) {
// Check bounds
if(pin_n > 57) {
return; // Out of bounds, ignoring
}
// Get the pin number in pin_bahia
byte pin = (pin_n - 1) / PINS_MULTI_AMOUNT;
if(pin_mode[pin] == MODE_DO) {
if(value == 0) {
digitalWrite(bahia_to_arduino[pin], LOW);
} else {
digitalWrite(bahia_to_arduino[pin], HIGH);
}
} else if(pin_mode[pin] == MODE_AO) {
if(value < 256) {
analogWrite(bahia_to_arduino[pin], value);
} // Ignoring values out of range
} // Ignoring pins configured as input
return;
}
// Perform a Enable/Disable sensor instruction
void instructionEnable(byte pin_n, boolean value) {
// Check bounds
if(pin_n > 57) {
return; // Out of bounds, ignoring
}
// Get the pin number in pin_bahia
byte pin = (pin_n - 1) / PINS_MULTI_AMOUNT;
// Check if is configured as output
if((pin_mode[pin] != MODE_AO) && (pin_mode[pin] != MODE_DO)) {
return;
}
// Check if is multiplexed
if(pin < 7) {
byte channel = (pin_n - 1) - (pin * PINS_MULTI_AMOUNT);
read_enabled_multiplexed[pin][channel] = value;
//TODO Optimize: analize if all the colums are false to disable pin in read_enable
} else {
read_enabled[pin] = value;
}
return;
}
// Perform a Configure pin mode instruction
void instructionConfigure(byte pin_n, int value) {
// Check bounds
if(pin_n > 57) {
return; // Out of bounds, ignoring
}
// Get the pin number in pin_bahia
byte pin = (pin_n - 1) / PINS_MULTI_AMOUNT;
switch(value) {
case 1: // Digital out
pinMode(bahia_to_arduino[pin], OUTPUT);
pin_mode[pin] = MODE_DO;
break;
case 2: // Digital in
pinMode(bahia_to_arduino[pin], INPUT);
pin_mode[pin] = MODE_DI;
break;
case 3: // "Analog out" (PWM)
if(can_pwm_output[pin]) {
pinMode(bahia_to_arduino[pin], OUTPUT);
pin_mode[pin] = MODE_AO;
}
break;
case 4: // Analog in
if(can_analog_input[pin]) {
pinMode(bahia_to_arduino[pin], INPUT);
pin_mode[pin] = MODE_AI;
}
break;
} // Ignoring unknown values
return;
}
// Read the current pin and channel, if needed. Then, broadcast the value through serial using OSC Protocol
// Note: This function check that the pin is configured as input, but it asumes you actually want to read the pin.
void read_and_broadcast(byte pin, byte channel) {
//Serial.print("Goind to read and broadcast: ");
//Serial.print(pin, DEC);
//Serial.print(", ");
//Serial.println(channel, DEC);
// Select channel, if needed
if(channel < PINS_MULTI_AMOUNT) {
// Note: HIGH is defined as 0x1 and LOW as 0x0 in wiring.h
digitalWrite(ADDR_A, channel & B00000001);
digitalWrite(ADDR_B, (channel & B00000010) >> 1);
digitalWrite(ADDR_C, (channel & B00000100) >> 2);
}
// Read the pin
int reported_value = 0;
if(pin_mode[pin] == MODE_DI) {
reported_value = digitalRead(bahia_to_arduino[pin]);
} else if(pin_mode[pin] == MODE_AI) {
reported_value = analogRead(bahia_to_arduino[pin]);
}
// Calculate the pin number
byte pin_n = 0;
if(pin < PINS_MULTI) {
pin_n = (pin * PINS_MULTI_AMOUNT) + channel + 1;
} else {
pin_n = (PINS_MULTI * PINS_MULTI_AMOUNT) + (pin - PINS_MULTI_AMOUNT) + 1;
}
// Broadcast the value
Serial.write("/ard/"); //OSC Address Pattern
Serial.print(BAHIA_ID, DEC);
Serial.write('/');
Serial.print(pin_n, DEC);
Serial.write("\0\0\0\0");
Serial.write(",i\0\0"); //OSC Type Tag String
Serial.write("\0\0"); //OSC Arguments
Serial.write(reported_value);
// For debug only
Serial.println("");
return;
}