Help with DataLogging

Hi,

I have been working with the Arduino for about a week now, the idea of this project is to log information from my race bike.
I want to log speed (via GPS later on), suspension travel, brake inputs, and throttle position.

I have managed to get all of the above except the Throttle sensor written to the SD, Using ADAfruits assembled logger BTW.

I can't see why at the moment. It prints 0.00 as a value regardless of input. I have basically copied the suspension travel code, which works great, but the TPS doesn't register...

I'll use a hall sensor for the wheel speed later, just trying it out with a reed for now.

Would anyone be kind enough to give some ideas? I know it's a bit ropey, but I've only been playing with it for 4 days. So pretty new to this stuff!

Thank you.

Sketch:

#include <SD.h>
const int chipSelect = 10;
int frontbrake = 2;
//calculations
//tire radius ~ 11.87 inches
//circumference = pi2r
#define reed A2//pin connected to read switch
//storage variables
int reedVal;
long timer;// time between one full rotation (in ms)
float mph;
float radius = 11.87;// tire radius (in inches)
float circumference;
int maxReedCounter = 100;//min time (in ms) of one rotation (for debouncing)
int reedCounter;

void setup() {

pinMode(frontbrake, INPUT);
reedCounter = maxReedCounter;
circumference = 23.14radius;
pinMode(reed, INPUT);
Serial.begin(9600);
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);

// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");

// TIMER SETUP- the timer interrupt allows precise timed measurements of the reed switch
//for more info about configuration of arduino timers see Arduino Playground - Timer1
cli();//stop interrupts
//set timer1 interrupt at 1kHz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;
// set timer count for 1khz increments
OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))8) - 1
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS11 bit for 8 prescaler
TCCR1B |= (1 << CS11);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();//allow interrupts
//END TIMER SETUP
}
ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
reedVal = digitalRead(reed);//get val of A2
if (reedVal){//if reed switch is closed
if (reedCounter == 0){//min time between pulses has passed
mph = (56.8
float(circumference))/float(timer);//calculate miles per hour
timer = 0;//reset timer
reedCounter = maxReedCounter;//reset reedCounter
}
else{
if (reedCounter > 0){//don't let reedCounter go negative
reedCounter -= 1;//decrement reedCounter
}
}
}
else{//if reed switch is open
if (reedCounter > 0){//don't let reedCounter go negative
reedCounter -= 1;//decrement reedCounter
}
}
if (timer > 1000){
mph = 0;//if no new pulses from reed switch- tire is still, set mph to 0
}
else{
timer += 1;//increment timer

}

}

void loop() {
// read the inputs on analog pins:
int frontsensor = analogRead(A0);
int rearsensor = analogRead(A1);
int leverstate = digitalRead(frontbrake);
int throttle = analogRead(A4);
// print out the values read:
float frontval = frontsensor * (125.0 / 1023); // NOTE: The 100.0 figure is the stroke length of the forks.
float rearval = rearsensor * (55.0 / 1023); // NOTE: The 50.0 figure is the stroke length of shock. If directly mounted.
float frlever = leverstate * (10 * 1); // Write the digital signal as a value 10. To make it readable on graph.
float gas = throttle * (100 / 1023); //Note: the 100 value here is the represent TPS as a %

// open the file. note that only one file can be open at a time,

File dataFile = SD.open("datalog.CSV", FILE_WRITE);

// if the file is available, write to it:
if (dataFile) {
dataFile.print(frontval);
dataFile.print(" , ");
dataFile.print(rearval);
dataFile.print(" , ");
dataFile.print(frlever);
dataFile.print(" , ");
dataFile.print(mph);
dataFile.print(" , ");
dataFile.print(gas);
dataFile.print(" , ");
dataFile.println();
dataFile.close();

// print to the serial port too:

}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.CSV");

return;} //If not available, do no more.

Serial.print(frontval);
Serial.print (" , ");
Serial.print(rearval);
Serial.println(" , ");
Serial.print(frlever);
Serial.print(" , ");
Serial.print(mph);
Serial.print(" , ");
Serial.print(gas);
Serial.print(" , ");

delay(250);

} // Delay time is recording accuracy, or resolution.

// NOTES:
// Write prog to be able to edit sample rate externally.
// Look at how to incorporate throttle position
// Rear wheel speed
// Write prog to record to SD Card.

//Connections:
//A0 = Front suspension POT
//A1 = Rear suspension POT
//A2 = Front Wheel speed Input (Hall Sensor) with 10kohm between A2 and 0v
//DI2 = Front brake switch

Please put your code inside CODE tags to stop the forum software from mangling it.

float gas = throttle * (100 / 1023);

The expression (100 / 1023) will evaluate to zero since all the values are integers. Change it to (100.0 / 1023.0) to make the compiler evaluate it as a floating point expression. I don't know whether that's the only problem, but I suggest you fix that and see what happens.

Ah! Of course! Thank you very much for that.

My next issue is a gear position indicator, I have converted the analog in (which is 0-5v from the bike) to voltage values that tie up with the sensor.

I'd like to print the gear to the SD (just using serial to get it right at the moment) in values of 10, just as a representation on the graph.

But... I'm unsure of how to specify what is printed at what voltage. Hopefully you can see what I'm trying to achieve in my sketch.

Any help would be greatly appreciated!

My sketch so far:

void setup() {

Serial.begin(9600);
}

void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);

//switching values are
//1 = 1.36v
//2 = 1.77v
//3 = 2.49v
//4 = 3.23v
//5 = 4.10v
//6 = 4.55v

{
if (voltage < 1.37)
Serial.print("10");
Serial.println();
}

{
if (voltage >1.76 <2.45);
Serial.print("20");
Serial.println();
}

{
if (voltage >2.48 <3.0);
Serial.print("30");
Serial.println();
}

{
if (voltage >3.0 <4.0);
Serial.print("40");
Serial.println();
}

delay(1000);
}

You can store your range data in arrays and refactor to make the code easier to read like this:

void loop() {

  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
 
  //switching values are
  //1 = 1.36v
  //2 = 1.77v
  //3 = 2.49v
  //4 = 3.23v
  //5 = 4.10v
  //6 = 4.55v

  const int gmax = 6;

  const float vmin[gmax + 1] = {0, 0.00, 1.76, 2.48, 3.0, 4.0, 4.5};
  const float vmax[gmax + 1] = {0, 1.37, 2.45, 3.00, 4.0, 4.2, 4.6};
 
  int i;

  for (i = 1; i <= gmax; i++) {
    if (voltage > vmin[i] && voltage < vmax[i]) {
      Serial.print (i *10, DEC);
      Serial.println ();
    }
  }
  delay(1000);
}
  {
  if (voltage >1.76 <2.45);
  Serial.print("20");
  Serial.println();
  }

I'm afraid that these pieces of code are complete garbage; while they may compile, they certainly don't do what you want.

To achieve what you're trying to do, you would want code more like this:

if (voltage <= 1.36)
{
	Serial.println("10");
}
else if (voltage <= 1.77)
{
	Serial.println("20");
}
else if (voltage <= 2.49)
{
	Serial.println("30");
}
else if (voltage <= 3.23)
{
	Serial.println("40");
}
else if (voltage <= 4.10)
{
	Serial.println("30");
}
else if (voltage <= 4.55)
{
	Serial.println("50");
}
else
{
	Serial.println("60");
}

I'm not sure what those values you're printing are supposed to be - there were some gaps in the ranges of values your code handled and I don't know whether they're intentional.

You could also put the threshold values and printed values in an array which is iterated in a FOR loop to reduce code duplication. It would make sense to me to put the numerical conversion in a function to separate that logic out from the logic to display it.

Excellent, thank you for your help guys.