Delta_G:
Delta_G:
char filename[FILENAME_SIZE];
This needs to be at global scope otherwise it is destroyed at the bottom of loop() and recreated again each pass through.
Thanks, I have changed this in my code...I was curious about this, but still very new to debugging in C++/with an arduino, so wasn't sure how to check it.
mistergreen:
Here is the full code. This is using an example from the ChibiOS as a backbone. The idea is to collect digital inputs from 6 IR beams every 2ms and record whether they are tripped or not. I have been debugging via the serial monitor, so the code for writing to the SD card is commented out/converted from file.print to Serial.print.
// Data logger based on a FIFO to decouple SD write latency from data
// acquisition timing.
//
// The FIFO uses two semaphores to synchronize between tasks.
#include <ChibiOS_AVR.h>
#include <SdFat.h>
//
// interval between points in units of 1024 usec
const uint16_t intervalTicks = 2;
#define FILENAME_SIZE 15
char filename[FILENAME_SIZE];
//------------------------------------------------------------------------------
// SD file definitions
//const uint8_t sdChipSelect = SS;
//SdFat sd;
//SdFile file;
//------------------------------------------------------------------------------
// Fifo definitions
// size of fifo in records
const size_t FIFO_SIZE = 50;
#define runTime 1000 //Run time in milliseconds
// count of data records in fifo
SEMAPHORE_DECL(fifoData, 0);
// count of free buffers in fifo
SEMAPHORE_DECL(fifoSpace, FIFO_SIZE);
// data type for fifo item
struct FifoItem_t {
uint32_t usec;
int value;
int value2;
int value3;
int value4;
int value5;
int value6;
int error;
#define IR1 4
#define IR2 5
#define IR3 6
#define IR4 7
#define IR5 8
#define IR6 9
};
// array of data items
FifoItem_t fifoArray[FIFO_SIZE];
//------------------------------------------------------------------------------
// Declare a stack with 32 bytes beyond task switch and interrupt needs.
static WORKING_AREA(waThread1, 32);
static msg_t Thread1(void *arg) {
// index of record to be filled
size_t fifoHead = 0;
// count of overrun errors
int error = 0;
// dummy data
int count = 0;
while (1) {
chThdSleep(intervalTicks);
// get a buffer
if (chSemWaitTimeout(&fifoSpace, TIME_IMMEDIATE) != RDY_OK) {
// fifo full indicate missed point
error++;
continue;
}
FifoItem_t* p = &fifoArray[fifoHead];
FifoItem_t* p2 = &fifoArray[fifoHead];
FifoItem_t* p3 = &fifoArray[fifoHead];
FifoItem_t* p4 = &fifoArray[fifoHead];
FifoItem_t* p5 = &fifoArray[fifoHead];
FifoItem_t* p6 = &fifoArray[fifoHead];
p->usec = micros();
p2->usec = micros();
p3->usec = micros();
p4->usec = micros();
p5->usec = micros();
p6->usec = micros();
// replace next line with data read from sensor such as
// p->value = analogRead(0);
p->value = digitalRead(IR1);
p2->value2 = digitalRead(IR2);
p3->value3 = digitalRead(IR3);
p4->value4 = digitalRead(IR4);
p5->value5 = digitalRead(IR5);
p6->value6 = digitalRead(IR6);
p->error = error;
error = 0;
// signal new data
chSemSignal(&fifoData);
// advance FIFO index
fifoHead = fifoHead < (FIFO_SIZE - 1) ? fifoHead + 1 : 0;
}
return 0;
}
//------------------------------------------------------------------------------
void setup() {
char inChar=-1; // Where to store the character read
byte index = 0; // Index into array; where to store the character
Serial.begin(115200);
pinMode(IR1, INPUT);
digitalWrite(IR1, HIGH);
pinMode(IR2, INPUT);
digitalWrite(IR2, HIGH);
pinMode(IR3, INPUT);
digitalWrite(IR3, HIGH);
pinMode(IR4, INPUT);
digitalWrite(IR4, HIGH);
pinMode(IR5, INPUT);
digitalWrite(IR5, HIGH);
pinMode(IR6, INPUT);
digitalWrite(IR6, HIGH);
// wait for USB Serial
while (!Serial) {}
// Read Mouse name from serial
Serial.println(F("Input mouse name"));
if (Serial.available() > 0) // Don't read unless
// there you know there is data
{
if(index < 15) // One less than the size of the array
{
inChar = Serial.read(); // Read a character
filename[index] = inChar; // Store it
index++; // Increment where to write next
filename[index] = '\0'; // Null terminate the string
}
}
Serial.println(filename);
while (!Serial.available());
// open file
// if (!sd.begin(sdChipSelect)
// || !file.open(filename, O_CREAT | O_WRITE | O_TRUNC)) {
// Serial.println(F("SD problem"));
// sd.errorHalt();
// }
// start kernel
chBegin(mainThread);
while (1);
}
//------------------------------------------------------------------------------
// main thread runs at NORMALPRIO
void mainThread() {
// FIFO index for record to be written
size_t fifoTail = 0;
// unsigned long currTime = millis();
// time in micros of last point
uint32_t last = 0;
// remember errors
bool overrunError = false;
// start producer thread
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);
// start SD write loop
while(millis() < runTime) {
// wait for next data point
chSemWait(&fifoData);
FifoItem_t* p = &fifoArray[fifoTail];
FifoItem_t* p2 = &fifoArray[fifoTail];
FifoItem_t* p3 = &fifoArray[fifoTail];
FifoItem_t* p4 = &fifoArray[fifoTail];
FifoItem_t* p5 = &fifoArray[fifoTail];
FifoItem_t* p6 = &fifoArray[fifoTail];
if (fifoTail >= FIFO_SIZE) fifoTail = 0;
// print interval between points
if (last) {
Serial.print(p->usec - last);
} else {
Serial.write("NA");
}
last = p->usec;
Serial.write(',');
Serial.print(p->value);
Serial.write(',');
Serial.print(p2->value2);
Serial.write(',');
Serial.print(p3->value3);
Serial.write(',');
Serial.print(p4->value4);
Serial.write(',');
Serial.print(p5->value5);
Serial.write(',');
Serial.print(p6->value6);
Serial.write(',');
Serial.print(p->error);
Serial.write(',');
Serial.println(millis());
// remember error
if (p->error) overrunError = true;
// release record
chSemSignal(&fifoSpace);
// advance FIFO index
fifoTail = fifoTail < (FIFO_SIZE - 1) ? fifoTail + 1 : 0;
// currTime = currTime + millis();
}
// close file, print stats and stop
// file.close();
Serial.println(F("Done"));
Serial.print(F("Thread1 unused stack: "));
Serial.println(chUnusedStack(waThread1, sizeof(waThread1)));
Serial.print(F("Heap/Main unused: "));
Serial.println(chUnusedHeapMain());
if (overrunError) {
Serial.println();
Serial.println(F("** overrun errors **"));
}
while (1);
}
//------------------------------------------------------------------------------
void loop() {
// not used
}