Hello everybody. I'm new to the Arduino forum and let me start by thanking you all for your contributions to the forum. It has been a huge help resource for me.
I am working on a Quadrotor that will use Arduino to do all the sensor processing, control and handle all telemetry.
The sensors i am using are an ADXL330 accelerometer and a HMC6352 compass.
Currently, i am testing data acquisition, using a serial port, to a computer. The program that reads the data was coded in ANSI C using Visual Studio 2005. The purpose of the code is for a later use in MatLab to produce a Simulink Block for data acquisition.
The message i am sending is something like:
"x2y1z99c350e" (where "e" stands for "message end").
in other words:
"x<xvalue>y<yvalue>z<yvalue>c<compass angle>e"
The problem is that the C program keeps crashing. I have tested and modified the program in several ocasions, googled and researched a lot, but i was not able to solve it so far. There are occasions when the program runs well, but as soon as i toutch the sensors it crashes. Bellow i show the code for the Arduino code, the ANSI C program, and an example of the program execution (as a console application).
Arduino code:
#include <Wire.h> //Library for I2C implementation using analog pins 4 (SDA) and 5 (SCL)
//Accelerometer variables
float ax,ay,az; //Acceleration values in m/s^2 for all three axis
float as=0.0049; //Arduino analog resolution (V/unit)
float zg=1.65; //Sensor zero g = Input Voltage/2 (V)
float sR=0.329; //Sensor resolution (V/g)
int fact=100; //Multiplicatin factor for sending data through the serial port
//Compass variables
int compassAddress = 0x42 >> 1; // compass I2C slave adress: 0x42
// because the wire.h library only uses the 7 bits most significant bits
// a shift necessary is to get the most significant bits.
int reading = 0; // Compass heading in degrees
void setup()
{
Wire.begin();
Serial.begin(9600); // Initialize serial communications with setup
}
void loop()
{
// get the most recent acceleration values for all three axis
ax = (analogRead(0)*as-zg)/sR;
ay = (analogRead(1)*as-zg)/sR;
az = (analogRead(2)*as-zg)/sR;
// Compass task 1: connect to the HMC6352 sensor
Wire.beginTransmission(compassAddress);
Wire.send('A'); // The ascii character "A" tells the compass sensor to send data
Wire.endTransmission();
// Compass task 2: wait for data processing
delay(10); // Compass datasheet says we need to wait at least 6000 microsegundos (0.006s) for data processing the sensor
// Compass task 3: Request heading
Wire.requestFrom(compassAddress, 2); // request 2 bytes of data
// Compass task 4: Get heading data
if(2 <= Wire.available()) // if 2 bytes are available
{
//16bit numbers can be broken in two 8 bit chunks. The first is called high byte and the second low byte
reading = Wire.receive(); // get high byte
reading = reading << 8; // shift high byte
reading += Wire.receive(); // get low byte
reading /= 10; // comment this line if you wish to get the heading in decidegrees instead of degrees
}
// output sensor data
Serial.print("x");
Serial.print(ax*fact,DEC); //Serial.print can not send floats, we can however multiply a decimal number by 100 and convert it into an integer
Serial.print("y");
Serial.print(ay*fact,DEC);
Serial.print("z");
Serial.print(az*fact,DEC);
Serial.print("c");
Serial.print(reading,DEC);
Serial.print("e");
Serial.flush();
}
ANSI C code:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
HANDLE hSerial;
int serialOpen(char *name);
BOOL serialRead(unsigned char *byte);
int serialWrite(unsigned char *data, int size);
void getSensorData(int *x,int *y,int *z,int *c);
//open Serial port; pass "COM1"/"COM2"/... for file name
int serialOpen(char *name)
{
DCB dSerial;
hSerial = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(hSerial == INVALID_HANDLE_VALUE)
return -1;
if(!GetCommState(hSerial, &dSerial))
return -2;
dSerial.BaudRate=CBR_9600;
dSerial.ByteSize=8;
dSerial.StopBits=ONESTOPBIT;
dSerial.Parity=NOPARITY;
if(!SetCommState(hSerial, &dSerial))
return -3;
return 0;
}
//read a single byte from the serial port
BOOL serialRead(unsigned char *byte)
{
int readSize;
if((ReadFile(hSerial, byte, 1, &readSize, NULL)) && (readSize>0))
if(readSize)
return TRUE;
return FALSE;
}
void getSensorData(int *x, int *y, int *z, int *c)
{
unsigned char b[1]={0}; //serial 1 char buffer
unsigned char valx[5]={0}; //buffer for accelerometer x value string
unsigned char valy[5]={0}; //buffer for accelerometer y value string
unsigned char valz[5]={0}; //buffer for accelerometer z value string
unsigned char valc[4]={0}; //buffer for compass angle string
unsigned char rbuffer[16]={0}; //buffer for Arduino message
int isx=0; //check for 'x' char in message
int isy=0; //check for 'y' char in message
int isz=0; //check for 'z' char in message
int isc=0; //check for 'c' char in message
int ise=0; //check for 'e' char in message
int i=0; //counter
i=0;
do{
serialRead(&b);
rbuffer[i]=b[0];
if(rbuffer[i]=='x') isx=1;
if(rbuffer[i]=='y') isy=1;
if(rbuffer[i]=='z') isz=1;
if(rbuffer[i]=='c') isc=1;
if(rbuffer[i]=='e') ise=1;
i++;
if(b[0]=='e' && (isx == 0 || isy == 0 || isz ==0 || isc == 0 || ise == 0)) //check for message integrity
{
i=0;
isx=0;
isy=0;
isz=0;
isc=0;
}
}while(b[0]!='e' && i<16 && (isx == 0 || isy == 0 || isz == 0 || isc == 0 || ise == 0));
printf("%s, %d\n",rbuffer, i); //print received message
if(rbuffer[0]=='x') //Extract accelerometer x value from message string
{
i=1;
do{
strncat(valx,&rbuffer[i],1);
i++;
}while(rbuffer[i]!='y');
*x=atoi(valx);
}
if(rbuffer[i]=='y') //Extract accelerometer y value from message string
{
i++;
do{
strncat(valy,&rbuffer[i],1);
i++;
}while(rbuffer[i]!='z');
*y=atoi(valy);
}
if(rbuffer[i]=='z') //Extract accelerometer z value from message string
{
i++;
do{
strncat(valz,&rbuffer[i],1);
i++;
}while(rbuffer[i]!='c');
*z=atoi(valz);
}
if(rbuffer[i]=='c') //Extract compass angle from message string
{
i++;
do{
strncat(valc,&rbuffer[i],1);
i++;
}while(rbuffer[i]!='e');
*c=atoi(valc);
}
}
void main(void)
{
int xx=0; //accelerometer x axis value
int yy=0; //accelerometer y axis value
int zz=0; //accelerometer z axis value
int cc=0; //compass angle value
int i=0; //counter
serialOpen("COM3"); //Open serial port
Sleep(2500);
while(!kbhit())
{
getSensorData(&xx,&yy,&zz,&cc);
printf("i:%d x:%d y:%d z:%d c:%d\n",i,xx,yy,zz,cc);
Sleep(10);
i++;
}
CloseHandle(hSerial); //Close serial port
}
Example run of the ANSI C program:
i:600 x:4 y:1 z:89 c:19
x4y3z89c19e, 11
i:601 x:4 y:3 z:89 c:19
x3y3z88c19e, 11
i:602 x:3 y:3 z:88 c:19
x3y6z88c22e, 11
i:603 x:3 y:6 z:88 c:22
x4y4z88c22e, 11
i:604 x:4 y:4 z:88 c:22
x6y3z91c22e, 11
i:605 x:6 y:3 z:91 c:22
x6y3z88c22e, 11
i:606 x:6 y:3 z:88 c:22
x7y6z92c26e, 11
i:607 x:7 y:6 z:92 c:26
x6y4z92c28e, 11
i:608 x:6 y:4 z:92 c:28
x7y6z91c28e, 11
i:609 x:7 y:6 z:91 c:28
x7y6z91c26e, 11
i:610 x:7 y:6 z:91 c:26
x7y4z92222222222[ch9568][ch9568][ch9568][ch9568][ch9568][ch9568][ch9568][ch9568], 16
As you can see from the example above, i was able to do 609 readings until i decided to move the sensors and the program crashed (again).
Thanks in advance to all of you

.