Show Posts
|
|
Pages: [1] 2 3
|
|
1
|
Using Arduino / Sensors / Re: Measuring dynamic pitch
|
on: April 08, 2011, 04:15:40 am
|
This is how I implemented the angle from the gyroscope: gyrovolt = gyroavg*5/1023; ygyro = -((gyrovolt-gyrooff)/gyrosens); if (ygyro > -1.2 && ygyro < 1.2){ ygyro = 0; } time = (millis()-first_time)/1000; first_time = millis(); anglegyro = anglegyro + ygyro*time;
I'll look up the Kalman filtering.
|
|
|
|
|
2
|
Using Arduino / Sensors / Re: Measuring dynamic pitch
|
on: April 07, 2011, 11:22:07 am
|
Thanks for all the reactions! If you are only interested in pitch then a single axis rate gyro can give you that, but only if the drift is corrected by a low-pass filtered reference vertical from an accelerometer (provided the motion is not too wild).
How would you best implement such a system where the gyro is compensated by the accelerometer? So, the 1-axis gyro and the 3-axis accelerometer would be enough? I tried to calculate the angle with the gyro and I tested it under static conditions (so the commented lines in the code). But this angle was far from the exact one... Is the code wrong, or is my gyroscope not good for this application?
|
|
|
|
|
3
|
Using Arduino / Sensors / Measuring dynamic pitch
|
on: April 07, 2011, 07:23:05 am
|
Hi all, I'm trying to measure pitch in dynamic conditions with an accelerometer (MMA7260q) and a GPS (ls20031). In static conditions (while standing still) the pitch angle sensed by the accelerometer (after some filtering) is quite good and stable. But in dynamic conditions, the accelerometer is not only influenced by the gravity acceleration but also by the movement acceleration and so the measured angle is junk. So I thought I would measure the movement acceleration by a GPS and subtract it from the accelerometer reading. But this don't improve the angle.. I also have a gyroscope (IDG1215) that I can use.. Here is my code: #include <TinyGPS.h>
// Accelerometer and gyroscope data float xkal, ykal, zkal, xvolt, yvolt, zvolt, gyrovolt, ygyro; float angleacc, anglegyro, prevAngle; const float accsens = 0.8; //166.67 count/g const float accoff = 1.65;//343.75; // count const float gyrooff = 1.35; const float gyrosens = 0.015; const float radToDegree = 180/3.14159265; const int calcount = 100; float first_time, time; float angle; float calx, caly, calz, calgyro;
// Kalman filter data const float Q = 1e-3; const float R = 0.1; float kal[3] = {337.59,337.59,501.27}; float P[3] = {10,10,10}; float kalmin[3]; float Pmin[3]; float K[3];
// GPS data TinyGPS gps; float gpsdump(TinyGPS &gps); bool feedgps(); float prevVel = 0; float accGPS; float dt, start1;
// Averaging data int teller = 0; float gyrocount; float accxcount, accycount, acczcount;
void setup() { Serial.begin(57600); Serial.println("Calibrating..."); calibrate(); Serial.println("[OK]"); }
void loop() { boolean newdata = false; unsigned long start = millis(); while(millis() - start < 100) { if (feedgps()){ newdata = true; } accxcount = accxcount + (analogRead(0) + calx); accycount = accycount + (analogRead(1) + caly); acczcount = acczcount + (analogRead(2) + calz); //gyrocount = gyrocount + (analogRead(3) + calgyro); teller++; } if(newdata){ accGPS = (float)gpsdump(gps); getAccAngle(accGPS, gyrocount/teller, accxcount/teller, accycount/teller, acczcount/teller, 1); } gyrocount = accxcount = accycount = acczcount = teller = 0; }
float getAccAngle(float acc2, float gyroavg, float accxavg, float accyavg, float acczavg, int pr){ // Time update kalmin[0] = kal[0]; kalmin[1] = kal[1]; kalmin[2] = kal[2]; Pmin[0] = P[0] + Q; Pmin[1] = P[1] + Q; Pmin[2] = P[2] + Q; // Measurement update K[0] = Pmin[0]/(Pmin[0]+R); K[1] = Pmin[1]/(Pmin[1]+R); K[2] = Pmin[2]/(Pmin[2]+R); float xmeas = accxavg - acc2; float ymeas = accyavg; float zmeas = acczavg; kal[0] = kalmin[0] + K[0]*(xmeas-kalmin[0]) ; // Should be 337.59 flat //Serial.println(kal[0]); kal[1] = kalmin[1] + K[1]*(ymeas-kalmin[1]) ; // Should be 337.59 flat kal[2] = kalmin[2] + K[2]*(zmeas-kalmin[2]) ; // Should be 501.27 flat P[0] = (1-K[0])*Pmin[0]; P[1] = (1-K[1])*Pmin[1]; P[2] = (1-K[2])*Pmin[2]; xvolt = kal[0]*5/1023; // Should be 1.65V flat yvolt = kal[1]*5/1023; // Should be 1.65V flat zvolt = kal[2]*5/1023; // Should be 2.45V fla xkal = (xvolt-accoff)/accsens; //Serial.println(xkal); ykal = (yvolt-accoff)/accsens; zkal = (zvolt-accoff)/accsens;
angleacc = atan2(xkal,sqrt(pow(ykal,2) + pow(zkal,2)))*radToDegree; // gyrovolt = gyroavg*5/1023; // ygyro = -((gyrovolt-gyrooff)/gyrosens); // if (ygyro > -1.2 && ygyro < 1.2){ // ygyro = 0; // } // time = (millis()-first_time)/1000; // first_time = millis(); // // anglegyro = anglegyro + ygyro*time; // angle = 0.98*(angle + ygyro*time) + 0.02*angleacc; // Printing the values
Serial.println(angleacc);
}
void calibrate(){ for (int i = 0; i < calcount; i++){ calx = calx + analogRead(0); caly = caly + analogRead(1); calz = calz + analogRead(2); calgyro = calgyro + analogRead(3); delay(50); } calx = 337.59 - calx/calcount; caly = 337.59 - caly/calcount; calz = 501.27 - calz/calcount; calgyro = 276.21 - calgyro/calcount; }
float gpsdump(TinyGPS &gps) { float flat, flon; unsigned long fix_age; gps.f_get_position(&flat, &flon, &fix_age); float falt = gps.f_altitude(); float speedms = gps.f_speed_mps(); //Serial.print("Latitude: "); Serial.println(flat,7); //Serial.print("Longitude: "); Serial.println(flon,7); //Serial.print("Altitude: "); Serial.println(falt, 5); //Serial.print("Speed m/s: "); Serial.println(speedms, 5); dt = (float)(millis()-start1)/1000; start1 = (float)(millis()); float temp = (float)(speedms-prevVel); prevVel = speedms; //Serial.print("Acceleration: ");Serial.println(temp/dt,5); return (float)(temp/dt);
} bool feedgps() { while (Serial.available()) { if (gps.encode(Serial.read()))
return true; } return false; }
Some help?
|
|
|
|
|
5
|
Using Arduino / Sensors / Re: IDG1215 gyroscope unstable
|
on: April 01, 2011, 11:32:19 am
|
|
I'am concentrating on the y-axis for now (using only 1 axis at the moment).
Now, the gyro itselfs works on an input supply voltage of 2.7-3.3V. Now thanks to the regulator on the breakout I can connect it to the 5V on the Arduino. My question:
When I want to calculate the voltage from the analogRead(), do I have to do: analogRead()*5/1023 or analogRead()*3.3/1023?
|
|
|
|
|
8
|
Using Arduino / Sensors / Re: Save data with Processing to .CSV
|
on: March 28, 2011, 12:56:41 pm
|
Well one thing I suspect is that the output.println...... line is being called every time a byte is read, rather than every three as you're intending, so only every third line is likely to be correct. But that's just a guess: what do you see on the serial monitor, what do you see in the file and how does it differ from what you expected?
I dont see how I have to change that println command Here is my serial monitor output: 267 323 524 273 313 516 280 314 514 286 338 517 281 316 520 285 328 521 278 319 515 275 326 516 265 314 512 277 315 522 280 334 511 274 320 516 276 331 519 280 324 515 276 329 515 285 323 513 290 327 521 271 334 523 269 316 517 269 320 514 272 327 513 296 330 515 262 318 515 274 320 510 282 325 510
Here is the CSV output: 268.78824,332.97647,505.48236 268.78824,332.97647,505.48236 268.78824,332.97647,505.48236 280.82355,320.9412,505.48236 280.82355,320.9412,505.48236 280.82355,320.9412,505.48236 264.7765,328.96472,509.4941 264.7765,328.96472,509.4941 264.7765,328.96472,509.4941 284.8353,324.95294,505.48236 284.8353,324.95294,505.48236 284.8353,324.95294,505.48236 292.85883,312.91766,505.48236 292.85883,312.91766,505.48236 292.85883,312.91766,505.48236 272.80002,316.9294,501.47058 272.80002,316.9294,501.47058 272.80002,316.9294,501.47058 280.82355,316.9294,509.4941 280.82355,316.9294,509.4941 280.82355,316.9294,509.4941 272.80002,316.9294,509.4941 272.80002,316.9294,509.4941 272.80002,316.9294,509.4941
The values are good, but it seems that the values from the monitor fluctuate much harder..
|
|
|
|
|
9
|
Using Arduino / Sensors / Re: Save data with Processing to .CSV
|
on: March 28, 2011, 12:10:28 pm
|
Oops, forgot! Now, I have values in my .csv file, but they dont match with the ones I get in my serial monitor import processing.serial.*;
PrintWriter output; Serial myPort; float[] serialInArray = new float[6]; int inByte = -1; float meas1, meas2, meas3 = 0; float kalx, kaly, kalz = 0; int serialCount = 0;
void setup() { println(Serial.list()); output = createWriter("accelerometer.csv"); myPort = new Serial(this, Serial.list()[1], 9600); }
void draw () { while (myPort.available() > 0) { int serialByte = myPort.read(); processByte(serialByte); output.println(map(meas1, 0, 255, 0, 1023) + "," + map(meas2, 0, 255, 0, 1023) + "," + map(meas3, 0, 255, 0, 1023)); } } void keyPressed() { output.flush(); output.close(); exit(); }
void processByte( int inByte) { serialInArray[serialCount] = inByte; serialCount++; if (serialCount > 2 ) { meas1 = serialInArray[0]; meas2 = serialInArray[1]; meas3 = serialInArray[2]; serialCount = 0; } }
|
|
|
|
|
10
|
Using Arduino / Sensors / Re: Save data with Processing to .CSV
|
on: March 28, 2011, 11:47:54 am
|
I want my data (collected through the analogRead() command) to be written to a .CSV file using Processing. I have an accelerometer with 3 analog inputs This is what I have at the moment (but not working) Arduino: void setup() { Serial.begin(9600); }
void loop() { Serial.print(map(analogRead(0), 0, 1023, 0, 255), BYTE); Serial.print(map(analogRead(1), 0, 1023, 0, 255), BYTE); Serial.print(map(analogRead(2), 0, 1023, 0, 255), BYTE); delay(50); } Processing: import processing.serial.*; PrintWriter output; Serial myPort; float[] serialInArray = new float[3]; int inByte = -1; float meas1, meas2, meas3 = 0; int serialCount = 0;
void setup() { println(Serial.list()); output = createWriter("accelerometer.csv"); myPort = new Serial(this, Serial.list()[1], 9600); }
void draw () { while (myPort.available() > 0) { int serialByte = myPort.read(); output.println(map(meas1, 0, 255, 0, 1023) + "," + map(meas2, 0, 255, 0, 1023) + "," + map(meas3, 0, 255, 0, 1023)); } } void keyPressed() { output.flush(); output.close(); exit(); }
void processByte( int inByte) { serialInArray[serialCount] = inByte; serialCount++; if (serialCount > 2 ) { meas1 = serialInArray[0]; meas2 = serialInArray[1]; meas3 = serialInArray[2]; serialCount = 0; } }
I only found examples how to write one byte, but here I have 3 bytes. The .csv file only contains zeros. thx
|
|
|
|
|
13
|
Using Arduino / Sensors / Save data with Processing to .CSV
|
on: March 28, 2011, 08:18:10 am
|
Hi, I want to send data from my Arduino to my PC and save the data to a CSV file with processing. But because I'm pretty new, I don't know how to do this. I read that I have to send it throught the serial port: meas[0] = analogRead(0); meas[1] = analogRead(1); meas[2] = analogRead(2); meas[3] = analogRead(3); meas[4] = analogRead(4); meas[5] = analogRead(5);
Serial.print(meas[0], DEC); Serial.print(meas[1], DEC); Serial.print(meas[2], DEC); Serial.print(meas[3],,DEC); Serial.print(meas[4],,DEC); Serial.println(meas[5],,DEC);
But how do I acces this data in Processing, and how do I create a CSV with it? Thx!
|
|
|
|
|