OK here’s my 1’st cut (untested) at the “EEPROM code”. It looks OK to my eye and compiles but I’ve yet to test it. ATM my Micro is in the basement performing airsoft timing duties. I’ll see if I have a chance to test later today perhaps (crappy weather now). Since you can program, you can look at the code and find/fix errors as well ! If I find any, or make improvements, I’ll post another version in another post.
The code below is supposed to do the following …
It has 2 basic modes, verbose and … well, not verbose, let’s call it EEPROM mode. In verbose mode it should operate much like the prior testbed code, except there’s no cap sensor code and it’s LED has been re-purposed.
Upon boot the code waits a few secs for you to get the serial monitor up and recording and then it dumps the EEPROM (presumably containing the prior runs data) to the serial monitor. Presently that’s 600 bytes of data but that number is changable via a define statement. Then the code performs and reports an offset measurement on the Hall sensor input (as the prior code did). Then the code proceeds into an infinite loop, measuring and reporting data at about 1 sec intervals. This slow looping will be accompanied by the green LED blinking on/off every other second. No data is stored to EEPROM. The red LED will go on and off with the detected signal being above or below a threshold. The threshold is presently set to 5 given your prior data, that may be something that needs “tuning” with any change to the magnetic properties of the testbed or test magnet. It’s a constant you can set at the top of the code.
If you compile the code with the verBose flag/boolean set to true, then the bootup process is the same as the above but the looping changes. As before the code enters an “infinite” loop but now the data is not reported but rather stored, over and over, in a array. The green LED goes on and stays on while sampling, giving you an indication of verbose mode or not. If a pulse above the threshold is detected then the red LED will go on and the loop will run for just another (max # samples/2), presently 300, and stop. The green LED will go out for a short time while writing the data to EEPROM. The LSB of magnitude data will be written to EEPROM and then the mode will be reset to verbose and finally the sampling loop restarted, but now in verbose mode (so EEPROM is preserved). LEDs will function as they do in verbose mode. The data in EEPROM will be dumped (but not lost) on the next reset. EEPROM remains preserved until the next pulse is detected in EEPROM mode, so you have multiple chances to retrieve it, if it’s missed on the reset. Just keep any magnets away from the testbed ! :mrgreen:
One thing that definitely needs tuning is the loop time in EEPROM mode. I was aiming for an interval of ~500 usec but I’ve yet to test, or benchmark, the code. So a placeholder value is presently in the constant. And since the timing isn’t all that important, I’ve not bothered to setup an interrupt to keep it constant. It’s timing will depend on the code execution time and so will vary with the code path. No biggie IMO.
//Curling testbed code v2.0
//put includes here
#include <EEPROM.h>
//define constants used
const int capPin = 2; //pin for cap sensor input
const int hallPin = A0; //pin for Hall sensor input
const int grnLEDpin = 5; //pin for green LED output
const int redLEDpin = 6; //pin for red LED output
const int magThrsh = 5; //magnitude of Hall reading needed to trip detection
const unsigned long looptimeM = 980; //loop time for verbose mode, msecs
const unsigned long looptimeU = 100; //loop time for EEPROM mode, usecs
//define variables used
bool verBose = false; //flag for verbose mode or EEPROM mode
bool detect = false; //flag indication pulse detected
int magOffset = 0; //offset from Hall sensor
int magReading = 0; //magnitude of raw Hall reading with offset removed
int cntr = 0; //count of readings > threshold
int iCtr = 0; //magnitude array index counter
#define iMax 600 //max number of samples to be stored
int iStop = iMax; //stop point for index
byte mag[iMax]; //array to store LSB (byte) of magnitudes
float magSum = 0.0; //sum used in computing offset
void setup() {
Serial.begin(9600);
pinMode(capPin, INPUT_PULLUP);
pinMode(redLEDpin, OUTPUT);
pinMode(grnLEDpin, OUTPUT);
digitalWrite(redLEDpin, LOW);
digitalWrite(grnLEDpin, LOW);
delay(6000);
//tell user that EEPROM dump is going to happen
Serial.println("Prepare to store EEPROM data ,");
delay(3000);
//dump EEPROM
for (int i = 0; i < iMax; i++) {
//dump samples in proper order
EEPROM.read(i);
}
//send a message re calibration
Serial.println("Prepare to perform offset calibration ,");
delay(3000); //wait 3 secs
Serial.println("Performing offset calibration ,");
delay(1000); //wait 1 sec
//take 20 A/D readings spaced 1 msec apart
for (int i = 0; i < 20; i++) {
magSum += float(analogRead(hallPin));
delay(1);
}
//now compute average
magOffset = int(magSum / 20.0);
Serial.println("Done ,");
Serial.print("Offset is ,");
Serial.println(magOffset);
Serial.println("Proceeding to measurements ,");
digitalWrite(grnLEDpin, HIGH);
}
void loop() {
//loop forever sampling Hall sensor until pulse is detected
//then store samples to EEPROM, if not verbose mode
//then loop in verbose mode, sending data, until reset
while (iCtr < iStop) {
//loop while taking Hall sensor readings
magReading = analogRead(hallPin);
mag[iCtr] = byte(abs(magReading - magOffset));
if (verBose) {
//send descriptions and data to serial monitor
Serial.print("raw Hall reading is ,");
Serial.print(magReading);
Serial.print(",");
Serial.print(" Feild strength is ,");
Serial.println(mag[iCtr]);
}
//Try to detect pulse leading edge
if (magReading > magThrsh) {
cntr ++;
}
else {
cntr --;
cntr = max(cntr, 0);
}
if (cntr > 3) {
// pulse detected
digitalWrite(redLEDpin, HIGH);
if (!verBose && !detect) {
detect = true;
//set stop point ~half number of samples into the future
iStop = iCtr + (iMax / 2);
if (iStop >= iMax) {
iStop -= iMax;
}
}
}
//increment counter for magnitude array, limit 0 to iMax-1
iCtr++;
if (iCtr >= iMax) {
iCtr = 0;
}
if (verBose) {
//set delay to get approx correct sampling interval
delay(looptimeM);
//in verbose mode blink LED
if (iCtr % 2) {
digitalWrite(grnLEDpin, LOW);
}
else {
digitalWrite(grnLEDpin, HIGH);
}
//in verbose mode turn off red LED if no signal
if (cntr == 0) {
digitalWrite(redLEDpin, LOW);
}
}
else {
//not verbose mode, use short delay
delayMicroseconds(looptimeU);
}
}
//peak detected, sampling done, turn on off green LED
digitalWrite(grnLEDpin, LOW);
//store data away into EEPROM
for (int i = 0; i < iMax; i++) {
//store samples in proper order in EEPROM
//iCtr was incremented and so left pointing to oldest sample
int ii = i + iCtr;
if (ii >= iMax) {
ii = 0;
}
EEPROM.write(i, mag[ii]);
}
//set mode to verBose and restart sampling
verBose = true;
iStop = iMax;
iCtr = 0;
cntr = 0;
}