Go Down

Topic: Slotcar speed controller with display and electronic memory project (Read 7541 times) previous topic - next topic

DuaneB

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
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

backbone

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

Code: [Select]

#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;
     

       
   }

}
Never to old to learn and I learn every day

wildbill

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.

DuaneB

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



Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

backbone

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. :-)

Paco
Never to old to learn and I learn every day

backbone

Wildbill,

Did the job and the EEPROM memory saving is working.
I divided the WRITE by 4 and mulitplied the READ by 4 too.
No hassle with low and high bytes saving and reading. Maybe in a later stage of the project.
If the value of the speedsensor differs +/- 1 this is no problem.

Next problem on the list is some pushbutton actions need to become push is one single step up or down in value.

I have seen a button libary for it but I couldnt got it to work sofar.
Even the samples cant be compiled.

Paco

Latest code

Code: [Select]

#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 led2Pin = 12;                // currently in use as a check option
const int ledPin = 13;                  // the number of the LED output pin
const int writebuttonPin = 10;         // currently used to store the speed min max values in the EEPROM

// 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;           // variable for reading the pushbutton status
int brakedownbuttonState = 0;         // variable for reading the pushbutton status
int writebuttonState = 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 = 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 speedcurveValueold = 0;
int speedstartValueold = 0;
int brakecurveValueold = 0;
int brakeValueold = 0;
int modelNameold = 0;
int minVal = 0;
int maxVal = 0;
int sensorMinold =0;
int sensorMaxold = 0;

void setup()
{
  Serial.begin(9600);                       // Output to serial writing
 
  pinMode(ledPin, OUTPUT);                  // initialize the led as a output control pin
  pinMode(led2Pin, OUTPUT);
  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);
   
  //+++++++++++ EEprom read +++++++++++++     
  minVal = EEPROM.read(0);           // read a byte from the current address of the EEPROM
  maxVal = EEPROM.read(1);           // read a byte from the current address of the EEPROM
  sensorMin = (minVal * 4);          // read the sensorMin value and multiply by 4
  sensorMax = (maxVal * 4);          // read the sensorMax value and multiply by 4
  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()
{
        //send data to serial port for debugging
      Serial.print("SPD=" );                       
      Serial.print(sensorValue);
      Serial.print(" BRK=" );                       
      Serial.print(brakeValue);
      Serial.print(" MIN=" );                       
      Serial.print((sensorMin/4));
      Serial.print(" MAX="  );
      Serial.println((sensorMax/4));

      delay(50);
     
      writebuttonState = digitalRead(writebuttonPin); //currently the speedsensor min and max values are stored here
      if (writebuttonState == HIGH) // values are divided by 4 due to the max of 255
      {EEPROM.write(0,sensorMin/4); EEPROM.write(1,(sensorMax/4)); digitalWrite(led2Pin, HIGH);}
      else
      digitalWrite(led2Pin, LOW);
 
  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 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 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;}
     

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

}




Never to old to learn and I learn every day

backbone

Just for those who are in need to build their own controller an overview of the current/optional functions (if the UNO pins allow).

Currently we use a potentiometer to control the speed.
The pot can wear and also have some tolerance in motion (slack) so we are trying to look in a simple contact less option.
Do not know if this is going to work, but when the project is ready we gonna try it this way.
Induction control with a little magnet in the trigger.
http://www.droboticsonline.com/index.php/buy-it-now-arduino-compatible-smd-magnetic-induction-sensor-cable.html
It says upto 3 cm reach and output is linear. Do not know yet which chip they use.

If you have other options for contact less control the easy way let me know.

Paco
Never to old to learn and I learn every day

backbone

What do I do wrong?

I downloaded and installed this button libary from the playground.
http://arduino.cc/playground/Code/Button

as per instruction added all needed.

When I debug I got a problem on this line
Button button = Button(10,PULLUP);
telling me that PULLUP was not declared in this scope

If I take a new sketch and add the sample code the same happens.

I like to use the uniquepress press function to have the software in the loop as long as the button is pressed only perfroms one add up or down of the value.

Code: [Select]
#include <Button.h>

/*3.create a Button object at pin 12
4.connect button between pin 12 and GND
5.
*/
    Button button = Button(12,PULLUP);
void setup()
    {pinMode(13,OUTPUT); //debug to led 13}

void loop()
{
    if(button.isPressed()){digitalWrite(13,HIGH);}
    else
    {digitalWrite(13,LOW);}
}
Never to old to learn and I learn every day

DuaneB

Hi,
   Its possible that this is another library which has not been updated to work with Arduino 1.0, there are quite a few, there is an easy fix if you search.

Duane B.

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

backbone

Duane,

It says version for Arduino 1.0 for the windows download.
Or am I wrong?

Paco
Never to old to learn and I learn every day

backbone

For those who follow the project.

The base settings can be done by 6 push buttons.
We now can write the data set in the controller in realtime to a PC control panel.
We can read on the controller the main data on a LCD.
Bought a LCD shield using to much data lines.  :(
Have ordered a 4 x20 IIC lcd to overcome this problem as I have enough analog lines not used. :)

Next step is to send the data from the PC control panel to the UNO so the data at both side is syncronized.
Still all is done by USB cable but the Bluetooth option is still on my list.

Paco
Never to old to learn and I learn every day

backbone

#26
Mar 26, 2012, 09:28 pm Last Edit: Mar 26, 2012, 09:30 pm by backbone Reason: 1
A screenshot of the current PC controlpanel of the data send by the controller.

Sofar my thanks go to Rob Tilltaart and Pauls for their assistance in the project.

Paco
Never to old to learn and I learn every day

backbone

We have the controller now running with a 4 x 20 display and six push buttons to control all settings this way by display.
The prototype contactless sensor is working too using a small magnet and a ratiometric hall sensor.
Ran only into Sram problems (2Kb seems a lot but in the end is nothing) with the UNO so might have to switch for prototyping to a Mega2560 board.

Paco
Never to old to learn and I learn every day

backbone

#28
May 03, 2012, 12:27 pm Last Edit: May 03, 2012, 05:44 pm by backbone Reason: 1
Are you still there?
The Sram problem made me to ordering a Mega2560 as there is no option for the UNO I found to enlarge the Sram.
The MENWIZ menu structure design by Roberto works and we now set all settings by using 4 buttons and the 4 x20 I2C display.
For the 6 quick access up /down buttons used on the controller handle and the 4 buttons for the menu navigation I tried to use 2 analog pins to reduce wires running from the handle to the controller board. beside + and - we then have 2 lines for the pushbuttons 2 for I2c for the display.
The analog port will detect  6 buttons each. Simple resistor ladder send a voltage to the Analog pin which convert it to statement.

More to come as the bluetooth modules are on their way too.
Then beside USB connection the BT connection to a BT equipped smart phone running Android will be an orther hurdle to take.

Paco
Never to old to learn and I learn every day

backbone

Here an over view picture on the prototype sofar.

Paco
Never to old to learn and I learn every day

Go Up