Arduino SensorBox firmware (with 4051 support!)

Andrew Benson's icon

Hello,
Having beat my head against the wall enough times with Firmata in educational environments, I put together a fairly simple Arduino firmware called SensorBox to just grab all the inputs, pack them up into a nice tidy bundle, and send them on to Max. On the Max side, every effort was made to avoid special voodoo, file dependencies, or obfuscation.

For those who need more than 6 analog inputs (who doesn't?), I also made a configurable version that allows you to interface a 4051 8x1 multiplexer chip to the analog pins, offering up to 96 possible inputs.

have fun.

Andrew B.

Tj Shredder's icon

Is there some sort of schematic for how to connect the multiplexer? Sounds interesting...

pdelges's icon
Andrew Benson's icon

The link Patrick gave should get you going. The 4051 chip is really easy to get connected, and just requires 3 I/0 pins. If you want to configure it to use multiple 4051 chips, you can control all of them with the same IO.

AB

Morgan's icon

Great! I'm going to use this in a project right now. Will be sure to report any problems/suggestions I have.

nycpntr@yahoo.com's icon

this is hot like summer andrew. Got it workin in no time flat....
Keep up the great work,
-M
www.maxabeles.com
(alot of Max/MSP work in my portfolio)

jasonD's icon

Hi Andrew, I think I was supposed to post here. Sorry about multiple posts - i cant delete the old one :-(

I am trying to hook up four 4051 multiplexers to use with your Sensorbox but wanted to check that I have the below code right, to get all four muxes in via the Arduino A0, A1, A2, A3 analog channels. Is this correct? Many thanks in advance.

//select analog channels to multiplex
char is_muxPIN[6] = {1,1,1,1,0,0};//This is the only line of code I need to // change; for A0, A1, A2, A3 analog pins hosting four muxes
char muxcount;//variable to store the number of multiplexed inputs

Rodrigo's icon

Is the data coming in supposed to only be 7bit? I'm only getting values from 0-127 on my first three analog ins and my second 3 inputs don't move at all (constant reading of '43' or something in that range).

Also is there a way to use this with i2c analog ins?

After (literally) months of banging my head against a wall trying to get a consistent and fast connection going (the last approach was using call-response, which kept breaking) this seems to work bang on (much better than my other approaches), but I'm having a hard time adapting my code to this (or vice versa).

I'm rocking a 9DOF setup with 3axis accel (pins 0, 1, 2), 3axis gyro (pins 6, 7, 3) and 3axis magnetometer (i2c). No digital I/O (other than an onboard LED for troubleshooting purposes).

Here's my attempted adaptation:

// i2c Arduino Library
#include

// 0011110b, i2c 7bit address of HMC5883
#define address 0x1E

int AccX, AccY, AccZ, GyroX, GyroY, GyroZ, MagX, MagY, MagZ;
char finish = 255;

#define aX A0
#define aY A1
#define aZ A2
#define gX A6
#define gY A7
#define gZ A3
#define LED1 5

void setup() {
//set LEDs as output pins
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);

// Start serial port at 57600 bps:
Serial.begin(57600);

// Start i2c communication
Wire.begin();

// Put the HMC5883 IC into the correct operating mode
Wire.beginTransmission(address); //open communication with HMC5883
Wire.write(0x02); //select mode register
Wire.write(0x00); //continuous measurement mode

// Send a byte to establish contact until receiver responds
Wire.endTransmission();
while (establishContact()==0){delay(100);} //wait for 99 byte

}

void loop() {
// Tell the HMC5883 where to begin reading data
Wire.beginTransmission(address);
Wire.write(0x03); //select register 3, X MSB register
Wire.endTransmission();

AccX = analogRead(aX);
AccY = analogRead(aY);
AccZ = analogRead(aZ);
GyroX = analogRead(gX);
GyroY = analogRead(gY);
GyroZ = analogRead(gZ);

// Read data from each axis of magnetometer, 2 registers per axis
Wire.requestFrom(address, 6);
if(6
MagX = Wire.read()<
MagX |= Wire.read(); // X lsb
MagZ = Wire.read()<
MagZ |= Wire.read(); // Z lsb
MagY = Wire.read()<
MagY |= Wire.read(); // Y lsb
// }

// Send sensor data out
digitalWrite(LED1, HIGH);

// Accelerometer X
Serial.write(highByte(AccX));
Serial.write(lowByte(AccX));

// Accelerometer Y
Serial.write(highByte(AccY));
Serial.write(lowByte(AccY));

// Accelerometer Z
Serial.write(highByte(AccZ));
Serial.write(lowByte(AccZ));

// Gyroscope X
Serial.write(highByte(GyroX));
Serial.write(lowByte(GyroX));

// Gyroscope Y
Serial.write(highByte(GyroY));
Serial.write(lowByte(GyroY));

// Gyroscope Z
Serial.write(highByte(GyroZ));
Serial.write(lowByte(GyroZ));

// Magnetometer X
Serial.write(highByte(MagX));
Serial.write(lowByte(MagX));

// Magnetometer Y
Serial.write(highByte(MagY));
Serial.write(lowByte(MagY));

// Magnetometer Z
Serial.write(highByte(MagZ));
Serial.write(lowByte(MagZ));

Serial.write(finish);
Serial.write(finish);
digitalWrite(LED1,LOW);
delay(10);

if(establishContact()==1) {
while(establishContact()==0) {delay(100);}//go into idle mode
}
}
}

char establishContact(void){
if (Serial.available() > 0) {
char checkup = Serial.read();
if (checkup==99) return 1;
else return 0;
}
else return 0;
}

Nishit Misty's icon

To RODRIGO

Hay thr
can you show me the max patch of your reply...??

Rodrigo's icon

Phew, old thread is old!

I don't remember what version of the patch this correlated to, but I believe this is the last 'working version' of this I had before I moved onto a different approach (http://x-io.co.uk).

Hope this helps!

Max Patch
Copy patch and select New From Clipboard in Max.