Slotcar speed controller with display and electronic memory project

Hi,

I am already in the progress with an other UNO project but this one came along. :grin:
Have made an all analog version slot car speed controller using PWM a few years back but now with the UNO on hand want to try it the micro-controller way.

My intentions are to first build a proto and learn to progrma and use the UNO this way.
So it will be step by step for hardware and software.

All slot car controllers I found on the web are using turnknobs to alter settings.
This all need to be done by touch and feel.
You cant recall any setting or simply see which the current setting is.
If someone by accident turns the knobs (it could be you) you have to start all over again.
So with the micro controller in connection with the display that should be easy to apply in wysiwyg :grin:

For the hardware prototyping I will use:
1 x UNO( Currently I use MEGA 2560 due to Sram shortage)
1 x 16 x2 lines diplay I2C
1 x BT modul with Android app to check and change settings by mobile phone or laptop.
1 x Hall sensor

Main functions for this controller:
Speed:
The trigger to control the speed will be using a linear hall sensor to have PWM control at the output.
Electronic settings that need to be altered by pushbuttons on the handle (+ and -) and stored in EEprom.
1] Start speed 0 to 70% in + and - direction (2 pushbuttons)
2] Exponential speed curve 0 to 50% in + and - direction (2 pushbuttons)
3] Other speed function might be added when the project progresses

Brake:
Electronic PWM settings that need to be altered by pushbuttons (+ and -) and stored in EEprom.
Brake:
1] Brake setting 0 to 100% in + and - direction (2 pushbuttons)when trigger is in neutral
2] Regenerative breaking can be switched on and off and hysteresus is adjustable from 0 to 25.
3] Regenerative break setting is adjustable by menu from 0 to 255.)

Display should have 3 or more screens to scroll through.
Scrolling is done by the 5 buttons on the display unit.
Screen 1: startspeed, speed curve, brake and brake curve in % this is the MAIN SCREEN.
Screen 2: graphic ( 2 x 16 blocks) of current setting of trigger speed and brake.
Screen 3: Modelname of settings loaded which can be retrieved from the EEprom.
Once you push one of the 3 major setting buttons (+ or -) the first is to activate screen 1 and the next pushes inside 5 seconds are to change and accept the button inputs and store them directly in the EEprom.

Maybe an ambisious project but I have the time.

Any thought and reflections on forehand are welcome.

Paco

1 Like

Here we have the main control handle with the 5 K ohm potentiometer.
Made out of pieces meatboard and shaped with high speed DREMEL tool.

Paco

Hi,
I used to build resin slot cars, what's the material the controller is made from, it looks like something you could make model parts from ?

Duane B

Duane,

The controller is made from MEAT BOARD (plastic). Easy to work on with electric (band saw) and high speed dremel tool.
Think when the project is finished and finalized a 3D printer should come in play to make the controller handle and incorporate all parts.
As you can see the trigger is placed offset to the left to have a better finger tip feeling.
Regular triggers are in line with the handle body.

Paco

1 Like

Hi,
I searched for 'meat board' after reading your post the first time, couldn't find anything that wasn't related to livestock !

Duane B

rcarduino.blogspot.com

@backbone: Are you aware that there are digital slot car systems out there (they aren't cheap, but they are interesting, if slot cars are your thing)? Maybe you should look into those and how they work (essentially constant power is applied to the rails, and individual cars are addressed by the control system (via micro-controllers on-board each car, powered by the rails) to change the speed of their motors via PWM. Other commands allow the cars to "change lanes" at lane-change points, so multiple cars can run in a single slot.

Duane,

This is what I use for it........... http://carrieandjonathan.com/wp-content/uploads/2012/01/free-plastic-cutting-board.jpg

Cr0sh,

I am fully aware of the digital versions and lane changing stuff. This is more for the pro's running 4 to 8 rail tracks with out lane changes.
This project is there too for those hobbyists who like to build their own custom version with standard available parts at a low price.
For me it is learning cycle where two things can be combined. :grin:

Here the first code by cut and paste and some regular thinking.
Sofar did not had the time to debug, must have some errors in it.
But it is a start......... :slight_smile:

#include <Servo.h>
#include <EEPROM.h>

// These constants won't change:
const int buttondisplayPin = A0;   // pin that the sensor is attached to
const int sensorPin = A1;          // pin that the sensor is attached to
const int speedPin = A2;        // pin that the LED is attached to for speed
const int brakePin = A3;        // pin that the LED is attached to for brake
const int speedoutPin = 2;            // pin that drives the speed servo and later the Speed FET section
const int brakeoutPin = 3;            // pin that drives the brake servo and later the Barke FET section
const int calibratePin = 4;        // pin that start the speed trigger calibration
const int startspeedupPin = 5;     // pin that start the start speed up
const int startspeeddownPin = 6;   // pin that start the start speed down
const int speedcurveupPin = 7;     // pin that start the speed curve up
const int speedcurvedownPin = 8;   // pin that start the speed curve down
const int brakeupPin = 9;          // pin that start the brake curve up
const int brakedownPin = 10;       // pin that start the brake curve down
const int handbrakePin = 11;       // pin that start the handbrake

// start reading from the first byte (address 0) of the EEPROM
int address = 0;
byte value;

int addr = 0;
int addr = 1;
int addr = 2;
int addr = 3;
int adrr = 4;

// variables:
int sensorValue = 0;         // the sensor value
int sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value
int startspeedValue = 0;     // startspeed value
int speedcurveValue = 0;     // speedcurve value
int brakeValue = 0;          // brake value

void setup() {
  
Serial.begin(9600);

pinMode(buttondisplayPin, INPUT);
pinMode(sensorPin, ANALOG);
pinMode(speeedPin, ANALOG);
pinMode(brakePin, ANALOG);
pinMode(calibratePin, INPUT);
pinMode(startspeedupPin, INPUT);
pinMode(startspeeddownPin, INPUT);
pinMode(speedcurveupPin, INPUT);
pinMode(speedcurvedownPin, INPUT);
pinMode(brakeupPin, INPUT);
pinMode(brakedownPin, INPUT);
pinMode(handbrakePin = INPUT;

void loop() 

//------------
 // read the stored values at power up of the controller from the EEPROM
 {
 // read a byte from the current address of the EEPROM
  sensorMin = EEPROM.read(0);
  sensorMax = EEPROM.read(1);
  startspeedValue = EEPROM.read(2);
  speedcurveValue = EEPROM.read(3);
  brakeValue = EEPROM.read(4);
 // advance to the next address of the EEPROM
  address = address + 1;
  
 // there are only 512 bytes of EEPROM, from 0 to 511, so if we're
 // on address 512, wrap around to address 0
 if (address == 512)
   address = 0;
    
 delay(500);
}

//----------
  // when digital input at pin (4) has been pressed once, calibration is started during the first 3 seconds and 
  // the values created by the potentiometer for full travel will be recorded.

{
  do while digitalWrite(calibratePin, HIGH)
  speedPin, 0; Brakepin, 0  // this prevents while calibrating that the output is activated
 
  while (millis() < 3000) {
    sensorValue = analogRead(sensorPin);

   // turn on LED to signal the start of the calibration period:
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
  
    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }
  
  // signal the end of the calibration period
  digitalWrite(13, LOW);
}

//--------------------------
{
  // read the trigger sensor:
  sensorValue = analogRead(sensorPin);

  // apply the calibration to the sensor reading
  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);

  // in case the sensor value is outside the range seen during calibration
  sensorValue = constrain(sensorValue, 0, 255);

  // fade the LED using the calibrated value:
  analogWrite(ledPin, sensorValue);
  //Send calibrated value also to pin 2 so rotate servo
  analogWrite(servoPin, sensorValue, 0, 255);
}

//-----------------------------
// write values to the EEprom
{
  // need to divide by 4 because analog inputs range from 0 to 1023 and each byte of the EEPROM can only hold a
  // value from 0 to 255.
  int val0 = sensorMin / 4;
  int val1 = sensorMax / 4;
  int val2 = startSpeedValue / 4;
  int val3 = speedcurveValue / 4;
  int val4 = brakeValue / 4;
  
  // write the value to the appropriate byte of the EEPROM.
  // these values will remain there when the board is turned off.
  EEPROM.write(1, val0);
  (2, val1);
  (3, val2);
  (4, val3);
  (5, val4);
  
  // advance to the next address.  there are 512 bytes in  the EEPROM, so go back to 0 when we hit 512.
  addr = addr + 1;
  if (addr == 512)
    addr = 0;
  
  delay(100);
}

I am very interested.
Please go on!!!!

Hi,
I know the 'meat board' now, I have seen it used as a source of tough plastic before, in the UK we call them 'cutting boards'.

You seem to be taking a big bite with your first attempt ! If the code you have cut and paste is the code you plan to use, there are a number of errors in it that I can see.

I would suggest breaking the project down into smaller steps, for example, on my programmable RC Controllers, there are either a set of 5 potentiometers or a menu system with up/down/set/cancel buttons and an LCD Display. A first step would be reading these values, storing them in program memory and using them to adjust the car performance. This is basically your proof of concept, once this works, then worry about storing values for later recall etc.

As a very first step, pick one value, throttle curve would see an obvious one and work on reading this and using it as an output. Then add a menu system and one more control until you have them all.

Just out of interest, what are you using Servos for ?

Duane B.

rcarduino.blogspot.com

Duane,

I am intending to do as you desricbed, first piece of code was just my first attemp.

As you can see in my code I like to work in blocks like I do in VB6. :grin:

Ok for the code I am much further then 2 weeks ago.
Got the sensor board in, not the display however.
I got the sensor speed ,sensor calibration and basic brake setup working.
Now I ran in a newbie problem I got not solved myself by google, forums, snippets or what ever.

Debugger CNTR+R says that EEprom was not declared in this scope in both void setup and void loop.

What for a simpel thing am I missing?

BTW the servo library was purely to see the output in relation to the servo arm move from 0 to max value and the curves it should make.
In the final project the outputs will be used to drive FET's.

Paco

#include <EEPROM.h>
#include <LiquidCrystal.h>

// constants that will not change:

const int displaybuttonPin = A0;        // pin that the 5 pushbutton from display is attached to
const int sensorPin = A1;               // pin that the sensor is attached to
const int brakeupbuttonPin = A2;        // the number of the input pin
const int brakedownbuttonPin = A3;      // the number of the input pin
const int speedupbuttonPin = A4;        // the number of the input pin
const int speeddownbuttonPin = A5;      // the number of the input pin
const int pwmoutspeedPin = 2;           // the number of the output pin
const int pwmoutbrakePin = 3;           // the number of the output pin
const int calibratebuttonPin = 4;       // the number of the input pin
const int speedcurveupbuttonPin = 5;    // the number of the input pin
const int speedcurvedownbuttonPin = 6;  // the number of the input pin
const int ledPin = 13;                  // the number of the LED output pin

// pin 7,8,9,10,11,112 are reserved for the display communication lines

// variables that will change:
int calibratebuttonState = 0;         // variable for reading the pushbutton status
int sensorValue = 0;                  // the speed sensor value
int sensorMin = 1023;                 // minimum sensor value
int sensorMax = 0;                    // maximum sensor value
int deathBand = 5;                    // setting for deathband around zero point of trigger
int speedcurveValue = 0;              // setting for speedcurve (exponentional)
int speedstartValue = 0;              // setting for starting point of speed
int brakecurveValue = 0;              // setting for brakecurve (exponentional)
int brakeValue = 0;                   // Brake value set
int modelName = 0;                    // Model name in number raging from 1 to 10 for later recall
int displaybuttonCount = 0;           // Counter for display button

void setup()
{
  pinMode(ledPin, OUTPUT);             // initialize the led as a output control pin
  pinMode(calibratebuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(brakeupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(brakedownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(speedupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(speeddownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  Serial.begin(9600);                  // Output to serial writing
  
  //+++++++++++ EEprom read +++++++++++++
      
  sensorMin = EEprom.read(0);        // read a byte from the current address of the EEPROM
  sensorMax = EEprom.read(1);        // read a byte from the current address of the EEPROM
  speedcurveValue = EEprom.read(2);  // read a byte from the current address of the EEPROM
  speedstartValue = EEprom.read(3);  // read a byte from the current address of the EEPROM
  brakecurveValue = EEprom.read(4);  // read a byte from the current address of the EEPROM
  brakeValue = EEprom.read(5);       // read a byte from the current address of the EEPROM
  modelName = EEprom.read(6);        // read a byte from the current address of the EEPROM
} 

void loop()
{
  calibratebuttonState = digitalRead(calibratebuttonPin); // read the state of the pushbutton value:

  
  if (calibratebuttonState == HIGH) // check if the calibrationpushbutton is pressed.
   {    // calibration mode 
    digitalWrite(ledPin, HIGH); sensorValue = analogRead(sensorPin); // turn LED on: 
    if (sensorValue > sensorMax) {sensorMax = sensorValue;} // record the maximum sensor value
    if (sensorValue < sensorMin) {sensorMin = sensorValue;} // record the minimum sensor value
   } 
  else 
   {     //regular mode
    digitalWrite(ledPin, LOW); // turn LED off:   
    sensorValue = analogRead(sensorPin); // read the sensor:
    sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);// apply the calibration to the sensor reading
    sensorValue = constrain(sensorValue, 0, 255); // in case the sensor value is outside the range seen during calibration

         // control the outputs
    if (sensorValue > deathBand) 
      {analogWrite(pwmoutspeedPin, sensorValue); analogWrite(pwmoutbrakePin, 0);}
    else
      {analogWrite(pwmoutspeedPin, 0); analogWrite(pwmoutbrakePin, 255); digitalWrite(ledPin, HIGH);}
        
        //send data to serial port
    //Serial.print("speed = " );                       
    //Serial.print(sensorValue);
    //Serial.print("brake = " );                       
    //Serial.println(pwmoutbrakePin);
    //delay(5);

        //++++++++++++ EEprom write ++++++++++++ 
   EEprom.read(0, sensorMin);        // write a byte to the current address of the EEPROM
   EEprom.read(1, sensorMax);        // write a byte to the current address of the EEPROM
   EEprom.read(2, speedcurveValue);  // write a byte to the current address of the EEPROM
   EEprom.read(3, speedstartValue);  // write a byte to the current address of the EEPROM
   EEprom.read(4, brakecurveValue);  // write a byte to the current address of the EEPROM
   EEprom.read(5, brakeValue);       // write a byte to the current address of the EEPROM
   EEprom.rear(6, modelName);        // write a byte to the current address of the EEPROM
    
    
 }

}

While reading the post I found some major errors.

Where is used read instead of write in the last part of the code.

Above mention problem still there but also realized in the loop we are contiously writing to the EEprom.

So I made some if staments to see if the code has changed since last time the controller was started,powered up or changeds in settinsg were made.

Paco

#include <EEPROM.h>
#include <LiquidCrystal.h>

// constants that will not change:

const int displaybuttonPin = A0;        // pin that the 5 pushbutton from display is attached to
const int sensorPin = A1;               // pin that the sensor is attached to
const int brakeupbuttonPin = A2;        // the number of the input pin
const int brakedownbuttonPin = A3;      // the number of the input pin
const int speedupbuttonPin = A4;        // the number of the input pin
const int speeddownbuttonPin = A5;      // the number of the input pin
const int pwmoutspeedPin = 2;           // the number of the output pin
const int pwmoutbrakePin = 3;           // the number of the output pin
const int calibratebuttonPin = 4;       // the number of the input pin
const int speedcurveupbuttonPin = 5;    // the number of the input pin
const int speedcurvedownbuttonPin = 6;  // the number of the input pin
const int ledPin = 13;                  // the number of the LED output pin

// pin 7,8,9,10,11,12 are reserved for the display communication lines

// variables that will change:
int calibratebuttonState = 0;         // variable for reading the pushbutton status
int sensorValue = 0;                  // the speed sensor value
int sensorMin = 1023;                 // minimum sensor value
int sensorMax = 0;                    // maximum sensor value
int deathBand = 5;                    // setting for deathband around zero point of trigger
int speedcurveValue = 0;              // setting for speedcurve (exponentional)
int speedstartValue = 0;              // setting for starting point of speed
int brakecurveValue = 0;              // setting for brakecurve (exponentional)
int brakeValue = 0;                   // Brake value set
int modelName = 0;                    // Model name in number raging from 1 to 10 for later recall
int displaybuttonCount = 0;           // Counter for display button
int sensorMinold = 0;
int sensorMaxold = 0;
int speedcurveValueold = 0;
int speedstartValueold = 0;
int brakecurveValueold = 0;
int brakeValueold = 0;
int modelNameold = 0;

void setup()
{
  pinMode(ledPin, OUTPUT);             // initialize the led as a output control pin
  pinMode(calibratebuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(brakeupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(brakedownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(speedupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(speeddownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  Serial.begin(9600);                  // Output to serial writing
  

  sensorMinold = sensorMin;
  sensorMaxold = sensorMax;
  speedcurveValueold = speedcurveValue;
  speedstartValueold = speedstartValue;
  brakecurveValueold = brakecurveValue;
  brakeValueold = brakeValue;
  modelNameold = modelName;
  
  //+++++++++++ EEprom read +++++++++++++
      
 sensorMin = EEprom.read(0);        // read a byte from the current address of the EEPROM
 sensorMax = EEprom.read(1);        // read a byte from the current address of the EEPROM
 speedcurveValue = EEprom.read(2);  // read a byte from the current address of the EEPROM
 speedstartValue = EEprom.read(3);  // read a byte from the current address of the EEPROM
 brakecurveValue = EEprom.read(4);  // read a byte from the current address of the EEPROM
 brakeValue = EEprom.read(5);       // read a byte from the current address of the EEPROM
 modelName = EEprom.read(6);        // read a byte from the current address of the EEPROM

} 

void loop()
{
  calibratebuttonState = digitalRead(calibratebuttonPin); // read the state of the pushbutton value:

  
  if (calibratebuttonState == HIGH) // check if the calibrationpushbutton is pressed.
   {    // calibration mode 
    digitalWrite(ledPin, HIGH); sensorValue = analogRead(sensorPin); // turn LED on: 
    if (sensorValue > sensorMax) {sensorMax = sensorValue;} // record the maximum sensor value
    if (sensorValue < sensorMin) {sensorMin = sensorValue;} // record the minimum sensor value
   } 
  else 
   {     //regular mode
    digitalWrite(ledPin, LOW); // turn LED off:   
    sensorValue = analogRead(sensorPin); // read the sensor:
    sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);// apply the calibration to the sensor reading
    sensorValue = constrain(sensorValue, 0, 255); // in case the sensor value is outside the range seen during calibration

         // control the outputs
    if (sensorValue > deathBand) 
      {analogWrite(pwmoutspeedPin, sensorValue); analogWrite(pwmoutbrakePin, 0);}
    else
      {analogWrite(pwmoutspeedPin, 0); analogWrite(pwmoutbrakePin, 255); digitalWrite(ledPin, HIGH);}
        
        //send data to serial port
    //Serial.print("speed = " );                       
    //Serial.print(sensorValue);
    //Serial.print("brake = " );                       
    //Serial.println(pwmoutbrakePin);
    //delay(5);


       //++++++++++++ EEprom write ++++++++++++ 
// I assume that the EEprom write values only needs to be done when the value from startup read has been changed or is changed while the power is on.
// Otherwise it is constantly writing to the EEprom in the LOOP which will use up the maximum write cycles specs

  If (sensorMin != sensorMinold)
  {EEprom.write(0,sensorMin); 
  sensorMinold == sensorMin;}
  
  If (sensorMax != sensorMaxold)
  {EEprom.write(1,sensorMax); sensorMaxold == sensorMax;}

  If (speedcurveValue != speedcurveValueold)
  {EEprom.write(2,speedcurveValue); speedcurveValueold == speedcurveValue;}

  If (speedstartValue != speedstartValueold)
  {EEprom.write(3,speedstartValue); speedstartValueold == speedstartValue;}
 
  If (brakecurveValue != brakecurveValueold)
  {EEprom.write(4,brakecurveValue); brakecurveValueold == brakecurveValue;}
 
  If (brakeValue != brakeValueold)
  {EEprom.write(5,brakeValue); brakeValueold == brakeValue;}

  If (modelName != modelNameold)
  {EEprom.write(6,modelName); modelNameold == modelName;}    
   }

}

It's EEPROM, not EEprom.

Thanks,

I told you newbie mistake. ]:slight_smile:

Will ammend the code.

OK,

Changed the newbie error and some more lower cast and uppercast errors.

Found out writing the EEPROM in the loop will reduce maximum write cycles.
So I added an if statement to check if the value to be stored have been changed.
If they did then write them to the EEPROM.

Current not used and not checked yet.

I added also one push button function for the brakevalue to test if it can be altered by using up or down button.
It works but have to find a code to reduce it to a single up or down code when the button is pressed.
Currently if I press the up or down button the loops in or de-crements the brake value rapidly.

Paco

#include <EEPROM.h>

// constants that will not change:
const int displaybuttonPin = A0;        // pin that the 5 pushbutton from display is attached to
const int sensorPin = A1;               // pin that the sensor is attached to
const int speedcurveupbuttonPin = A2;    // the number of the input pin
const int speedcurvedownbuttonPin = A3;  // the number of the input pin
const int speedstartupbuttonPin = A4;        // the number of the input pin
const int speedstartdownbuttonPin = A5;      // the number of the input pin
const int pwmoutspeedPin = 2;           // the number of the output pin
const int pwmoutbrakePin = 3;           // the number of the output pin
const int calibratebuttonPin = 4;       // the number of the input pin
const int brakeupbuttonPin = 5;        // the number of the input pin
const int brakedownbuttonPin = 6;      // the number of the input pin
const int ledPin = 13;                  // the number of the LED output pin

// pin 7,8,9,10,11,12 are reserved for the display communication lines

// variables that will change:
int calibratebuttonState = 0;         // variable for reading the pushbutton status
int brakeupbuttonState = 0;
int brakedownbuttonState = 0;
int sensorValue = 0;                  // the speed sensor value
int sensorMin = 1023;                 // minimum sensor value
int sensorMax = 0;                    // maximum sensor value
int deathBand = 10;                   // setting for deathband around zero point of trigger
int speedcurveValue = 0;              // setting for speedcurve (exponentional)
int speedstartValue = 0;              // setting for starting point of speed
int brakecurveValue = 0;              // setting for brakecurve (exponentional)
int brakeValue = 125;                 // Brake value set
int modelName = 9;                    // Model name in number raging from 1 to 10 for later recall
int displaybuttonCount = 0;           // Counter for display button
int sensorMinold = 0;
int sensorMaxold = 0;
int speedcurveValueold = 0;
int speedstartValueold = 0;
int brakecurveValueold = 0;
int brakeValueold = 0;
int modelNameold = 0;

Button button = Button(4,PULLUP);

void setup()
{
  pinMode(ledPin, OUTPUT);                  // initialize the led as a output control pin
  pinMode(calibratebuttonPin, INPUT);       // initialize the pushbutton pin as an input control pin
  pinMode(brakeupbuttonPin, INPUT);         // initialize the pushbutton pin as an input control pin
  pinMode(brakedownbuttonPin, INPUT);       // initialize the pushbutton pin as an input control pin
  pinMode(speedstartupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(speedstartdownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(speedcurveupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(speedcurvedownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  Serial.begin(9600);                       // Output to serial writing
  
  sensorMinold = sensorMin;
  sensorMaxold = sensorMax;
  speedcurveValueold = speedcurveValue;
  speedstartValueold = speedstartValue;
  brakecurveValueold = brakecurveValue;
  brakeValueold = brakeValue;
  modelNameold = modelName;
  
  //+++++++++++ EEprom read +++++++++++++
      
 //sensorMin = EEPROM.read(0);        // read a byte from the current address of the EEPROM
 //sensorMax = EEPROM.read(1);        // read a byte from the current address of the EEPROM
 //speedcurveValue = EEPROM.read(2);  // read a byte from the current address of the EEPROM
 //speedstartValue = EEPROM.read(3);  // read a byte from the current address of the EEPROM
 //brakecurveValue = EEPROM.read(4);  // read a byte from the current address of the EEPROM
 //brakeValue = EEPROM.read(5);       // read a byte from the current address of the EEPROM
 //modelName = EEPROM.read(6);        // read a byte from the current address of the EEPROM

} 

void loop()
{
  calibratebuttonState = digitalRead(calibratebuttonPin); // read the state of the pushbutton value:

  if (calibratebuttonState == HIGH) // check if the calibrationpushbutton is pressed.
   {    // calibration mode 
    digitalWrite(ledPin, HIGH); sensorValue = analogRead(sensorPin); // turn LED on:
    analogWrite(pwmoutspeedPin, 0); analogWrite(pwmoutbrakePin, 0); 
    if (sensorValue > sensorMax) {sensorMax = sensorValue;} // record the maximum sensor value
    if (sensorValue < sensorMin) {sensorMin = sensorValue;} // record the minimum sensor value
    
   } 
  else 
   {     //regular speed / brake mode
    digitalWrite(ledPin, LOW); // turn LED off:   
    sensorValue = analogRead(sensorPin); // read the sensor:
    sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);// apply the calibration to the sensor reading
    sensorValue = constrain(sensorValue, 0, 255); // in case the sensor value is outside the range seen during calibration
    brakeValue = constrain(brakeValue, 1, 254); // in case the sensor value is outside the range seen during calibration
         // control the outputs
      if (sensorValue > deathBand) {analogWrite(pwmoutspeedPin, sensorValue); analogWrite(pwmoutbrakePin, 0  ); }
        else
      {analogWrite(pwmoutspeedPin, 0); analogWrite(pwmoutbrakePin, brakeValue); digitalWrite(ledPin, HIGH);}

      //     +++++ check button activities +++++++
      brakeupbuttonState = digitalRead(brakeupbuttonPin);
      brakedownbuttonState = digitalRead(brakedownbuttonPin);
      
      if (brakeupbuttonState == HIGH) {brakeValue = brakeValue + 1;}
      if (brakedownbuttonState == HIGH) {brakeValue = brakeValue - 1;}
      if (speedstartupbuttonPin == HIGH) {speedstartValue= speedstartValue + 1;}
      if (speedstartdownbuttonPin == HIGH) {speedstartValue= speedstartValue - 1;}
      if (speedcurveupbuttonPin == HIGH) {speedcurveValue = speedcurveValue +1;}
      if (speedcurvedownbuttonPin == HIGH) {speedcurveValue = speedcurveValue -1;}

       //++++++++++++ EEprom write ++++++++++++ 
      //if (sensorMin != sensorMinold)
      //{EEPROM.write(0,sensorMin); sensorMinold == sensorMin;}
      //if (sensorMax != sensorMaxold)
      //{EEPROM.write(1,sensorMax); sensorMaxold == sensorMax;}
      //if (speedcurveValue != speedcurveValueold)
      //{EEPROM.write(2,speedcurveValue); speedcurveValueold == speedcurveValue;}
      //if (speedstartValue != speedstartValueold)
      //{EEPROM.write(3,speedstartValue); speedstartValueold == speedstartValue;}
      //if (brakecurveValue != brakecurveValueold)
      //{EEPROM.write(4,brakecurveValue); brakecurveValueold == brakecurveValue;}
      //if (brakeValue != brakeValueold)
      //{EEPROM.write(5,brakeValue); brakeValueold == brakeValue;}
      //if (modelName != modelNameold)
      //{EEPROM.write(6,modelName); modelNameold == modelName;}  
      
      //send data to serial port
      Serial.print("speed = " );                       
      Serial.print(sensorValue);
      Serial.print("    brake = " );                       
      Serial.println(brakeValue);
      delay(20); 
   }

}

I stumbled in a few problems.

Current anoing one:
When I start the project and calibrate the speedsensor the output is nicely moving between 0 and 255.
As soon as I start the serial monitor the project resets and the calibration setting is affected. I have to recalibrate with the serial monitor screen running again.
As long as the monitor is open no problem. As soon as I close and open it same problem.

What can sause this effect. The serial monitor is just readig and not sending data to the UNO.

Paco

Hi,

Thats standard behaviour for an UNO, to reset on serial connection. I am sure there arensimple work arounds if you search for 'UNO disable auto reset'

Duane B

rcarduino.blogspot.com

OK,

As the serialmonitor is only for debuggung now I leave it as it is.

Now further with a more serious issue.
The sensorMin and sensorMax value need to be stored in the EEPROM so once a first calibration of the speedsensor has been performed at a new startup it should read the values for sensorMin and sensorMax from the EEPROM.
Simple.

For some odd reason it does not do that.
In the serial monitor I see the values 275 and 441 as lowest and highsest vales after calibration.
I perform a manual write by a pushbutton to the EEPROM for address 0 and 1
But after sending this data to the EEPROM and restart the saved data is not read.

For the brakevalue I perform same write/read and that is working nicely.

Paco

#include <EEPROM.h>



// constants that will not change:

const int displaybuttonPin = A0;        // pin that the 5 pushbutton from display is attached to
const int sensorPin = A1;               // pin that the sensor is attached to
const int speedcurveupbuttonPin = A2;    // the number of the input pin
const int speedcurvedownbuttonPin = A3;  // the number of the input pin
const int speedstartupbuttonPin = A4;        // the number of the input pin
const int speedstartdownbuttonPin = A5;      // the number of the input pin
const int pwmoutspeedPin = 2;           // the number of the output pin
const int pwmoutbrakePin = 3;           // the number of the output pin
const int calibratebuttonPin = 4;       // the number of the input pin
const int brakeupbuttonPin = 5;        // the number of the input pin
const int brakedownbuttonPin = 6;      // the number of the input pin
const int ledPin = 13;                  // the number of the LED output pin
const int writebuttonPin = 10;
const int led2Pin = 12;
// pin 7,8,9,10,11,12 are reserved for the display communication lines

// variables that will change:
int calibratebuttonState = 0;         // variable for reading the pushbutton status
int brakeupbuttonState = 0;
int brakedownbuttonState = 0;
int writebuttonState = 0;
int sensorValue = 0;                  // the speed sensor value
int sensorMin = 1023;                 // minimum sensor value
int sensorMax = 0;                    // maximum sensor value
int deathBand = 10;                   // setting for deathband around zero point of trigger
int speedcurveValue = 0;              // setting for speedcurve (exponentional)
int speedstartValue = 0;              // setting for starting point of speed
int brakecurveValue = 0;              // setting for brakecurve (exponentional)
int brakeValue = 125;                 // Brake value set
int modelName = 9;                    // Model name in number raging from 1 to 10 for later recall
int displaybuttonCount = 0;           // Counter for display button
int sensorMinold = 0;
int sensorMaxold = 0;
int speedcurveValueold = 0;
int speedstartValueold = 0;
int brakecurveValueold = 0;
int brakeValueold = 0;
int modelNameold = 0;
int sensorMin1 = 0;
int sensorMax1 = 0;

void setup()
{
  Serial.begin(9600);                       // Output to serial writing
  
  pinMode(ledPin, OUTPUT);                  // initialize the led as a output control pin
  pinMode(calibratebuttonPin, INPUT);       // initialize the pushbutton pin as an input control pin
  pinMode(brakeupbuttonPin, INPUT);         // initialize the pushbutton pin as an input control pin
  pinMode(brakedownbuttonPin, INPUT);       // initialize the pushbutton pin as an input control pin
  pinMode(speedstartupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(speedstartdownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(speedcurveupbuttonPin, INPUT);    // initialize the pushbutton pin as an input control pin
  pinMode(speedcurvedownbuttonPin, INPUT);  // initialize the pushbutton pin as an input control pin
  pinMode(writebuttonPin, INPUT);
  pinMode(led2Pin, OUTPUT);
  //+++++++++++ EEprom read +++++++++++++
      
 
  sensorMin1 = EEPROM.read(0);        // read a byte from the current address of the EEPROM
  sensorMax1 = EEPROM.read(1);        // read a byte from the current address of the EEPROM  
 //speedcurveValue = EEPROM.read(2);  // read a byte from the current address of the EEPROM
 //speedstartValue = EEPROM.read(3);  // read a byte from the current address of the EEPROM
 //brakecurveValue = EEPROM.read(4);  // read a byte from the current address of the EEPROM
 brakeValue = EEPROM.read(5);       // read a byte from the current address of the EEPROM
 //modelName = EEPROM.read(6);        // read a byte from the current address of the EEPROM
 delay (500);

} 

void loop()
{
       // manual write to the EEProm of address 0 and 1
       writebuttonState = digitalRead(writebuttonPin); 
       if (writebuttonState == HIGH)
       {EEPROM.write(0,sensorMin); EEPROM.write(1,sensorMax); digitalWrite(led2Pin, HIGH);}
       else
       {digitalWrite(led2Pin, LOW);}
       
  //send data to serial port
      Serial.print("SPD=" );                       
      Serial.print(sensorValue);
      Serial.print(" BRK=" );                       
      Serial.print(brakeValue);
      Serial.print(" MIN=" );                       
      Serial.print(sensorMin);
      Serial.print(" MAX=" );                       
      Serial.print(sensorMax);
      Serial.print(" MINWR=" );                       
      Serial.print(sensorMin1);
      Serial.print(" MAXWR=" );                       
      Serial.println(sensorMax1);
      

      delay(20);

  
  calibratebuttonState = digitalRead(calibratebuttonPin); // read the state of the pushbutton value:

  if (calibratebuttonState == HIGH) // check if the calibrationpushbutton is pressed.
   { 
     // calibration mode for the full throw of the speedsensor trigger
    digitalWrite(ledPin, HIGH); sensorValue = analogRead(sensorPin); // turn LED on:
    analogWrite(pwmoutspeedPin, 0); analogWrite(pwmoutbrakePin, 0); 
    if (sensorValue > sensorMax) {sensorMax = sensorValue;} // record the maximum sensor value
    if (sensorValue < sensorMin) {sensorMin = sensorValue;} // record the minimum sensor value 
   } 
  else 
   { 
     //regular speed / brake mode
    digitalWrite(ledPin, LOW); // turn LED off:
   
    sensorValue = analogRead(sensorPin); // read the sensor:
    sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);// apply the calibration to the speed sensor reading
    sensorValue = constrain(sensorValue, 0, 255); // in case the sensor value is outside the range seen during calibration
    brakeValue = constrain(brakeValue, 0, 255); // in case the sensor value is outside the range
         // control the outputs
      if (sensorValue > deathBand) {analogWrite(pwmoutspeedPin, sensorValue); analogWrite(pwmoutbrakePin, 0  ); }
        else
      {analogWrite(pwmoutspeedPin, 0); analogWrite(pwmoutbrakePin, brakeValue); digitalWrite(ledPin, HIGH);}
      

      //     +++++ check button activities +++++++
      brakeupbuttonState = digitalRead(brakeupbuttonPin);
      brakedownbuttonState = digitalRead(brakedownbuttonPin);
      
      if (brakeupbuttonState == HIGH) {brakeValue = brakeValue + 1;}
      if (brakedownbuttonState == HIGH) {brakeValue = brakeValue - 1;}
      //if (speedstartupbuttonPin == HIGH) {speedstartValue= speedstartValue + 1;}
      //if (speedstartdownbuttonPin == HIGH) {speedstartValue= speedstartValue - 1;}
      //if (speedcurveupbuttonPin == HIGH) {speedcurveValue = speedcurveValue +1;}
      //if (speedcurvedownbuttonPin == HIGH) {speedcurveValue = speedcurveValue -1;}



       //++++++++++++ EEprom write ++++++++++++ 
      //if (sensorMin != sensorMinold)
      //{EEPROM.write(0,sensorMin); sensorMinold == sensorMin;}
      //if (sensorMax != sensorMaxold)
      //{EEPROM.write(1,sensorMax); sensorMaxold == sensorMax;}
      //if (speedcurveValue != speedcurveValueold)
      //{EEPROM.write(2,speedcurveValue); speedcurveValueold == speedcurveValue;}
      //if (speedstartValue != speedstartValueold)
      //{EEPROM.write(3,speedstartValue); speedstartValueold == speedstartValue;}
      //if (brakecurveValue != brakecurveValueold)
      //{EEPROM.write(4,brakecurveValue); brakecurveValueold == brakecurveValue;}
      if (brakeValue != brakeValueold)
      {EEPROM.write(5,brakeValue); brakeValueold == brakeValue;}
      //if (modelName != modelNameold)
      //{EEPROM.write(6,modelName); modelNameold == modelName;}
      

      //sensorMinold = sensorMin;
      //sensorMaxold = sensorMax;
      //speedcurveValueold = speedcurveValue;
      //speedstartValueold = speedstartValue;
      //brakecurveValueold = brakecurveValue;
      brakeValueold = brakeValue;
      //modelNameold = modelName;
      

       
   }

}

EEPROM write takes a byte parameter. Your 275 and 441 values are too big. You will need to write two bytes per calibration value - take a look at the lowbyte and highbyte functions.

Hi Backbone,

Looking at all the sections of your code that are commented out, it looks like you should start using versions. Strip out all the commented out code and save your project as SCSC_V1. If you add another feature, make it version 2 and so on. If you get to version 7 and something doesn't work its great to have six earlier versions that do to fall back on.

I do this all the time and it saves so much time.

Duane B.

rcarduino.blogspot.com

Thanks Duane,

I will have a look at low and high byte.
I thought 1024 was the limit not 255.
bits,bytes,niblles........confusing.

I am used of commeting things out for debugging.
This is already version 9. :slight_smile:

Paco