Jump to content

NLCbanner2024.jpg.2478be509670e60c2d6efd04834b8b47.jpg

Digital Oscilloscope for Testing & Debugging Astro Remote Controls


Gina

Recommended Posts

Hi Gina,

Looking at your sketch, for your output pin definitions,

14 hours ago, Gina said:

int redPin = 5; int orangePin = 6; int yellowPin = 9; int greenPin = 10; int bluePin = 11;

shouldn't these be A5, A6, etc because you are using them as analog outputs.

Just a thought,

Regards, Hugh 

Link to comment
Share on other sites

  • Replies 180
  • Created
  • Last Reply
15 hours ago, Stub Mandrel said:

You have remembered to program the CLKDIV8 fuse haven't you, otherwise it will run at an eighth of the speed you expect...

Missed your post somehow - sorry about that.  No I haven't programmed the fuse - didn't know about that.  Guess that explains the slowness.  In this case speed doesn't matter as long as it isn't thousands of times slower than normal.

Link to comment
Share on other sites

2 minutes ago, hughgilhespie said:

Hi Gina,

Looking at your sketch, for your output pin definitions,

shouldn't these be A5, A6, etc because you are using them as analog outputs.

Just a thought,

Regards, Hugh 

I don't think so.  They are digital PWM outputs and the LEDs work correctly when programmed directly.  Thanks for the thought :)

Link to comment
Share on other sites

Found it!!  Faulty switch/case syntax.  Missed out curly brackets in case statements.  Should be

switch (var) {
    case 1:
      {
      //do something when var equals 1
      int a = 0;
      .......
      .......
      }
      break;
    default:
      // if nothing else matches, do the default
      // default is optional
    break;
  }

Which condenses to

switch (var) {
    case 1: { int a = 0; ...} break;
    case 2: { int b = 3; ...} break;
    default:
      // if nothing else matches, do the default
      // default is optional
    break;
  }

 

Link to comment
Share on other sites

This line doesn't return from anything - you are still in the main loop and not a sub routine

if (chargeLevel == oldLevel) return;  //  no change so do nothing

The loop will just carry on to these and flash the LED on and off

switch (oldLevel) {
    case 0:  analogWrite(redPin,0); break;
    case 1:  analogWrite(orangePin,0); break;
    case 2:  analogWrite(yellowPin,0); break;
    case 3:  analogWrite(greenPin,0); break;
    case 4:  analogWrite(bluePin,0); break;
}
//
// and turn new LED on
switch (chargeLevel) {
    case 0: analogWrite(redPin,redBrightness); break;
    case 1: analogWrite(orangePin,orangeBrightness); break;
    case 2: analogWrite(yellowPin,yellowBrightness); break;
    case 3: analogWrite(greenPin,greenBrightness); break;
    case 4: analogWrite(bluePin,blueBrightness); break;
  }

Try this

if (chargeLevel != oldLevel) {
    //
    // chargeLevel has changed so change LED
    // turn old LED off
    switch (oldLevel) {
      case 0:  analogWrite(redPin, 0); break;
      case 1:  analogWrite(orangePin, 0); break;
      case 2:  analogWrite(yellowPin, 0); break;
      case 3:  analogWrite(greenPin, 0); break;
      case 4:  analogWrite(bluePin, 0); break;
    }
    //
    // and turn new LED on
    switch (chargeLevel) {
      case 0: analogWrite(redPin, redBrightness); break;
      case 1: analogWrite(orangePin, orangeBrightness); break;
      case 2: analogWrite(yellowPin, yellowBrightness); break;
      case 3: analogWrite(greenPin, greenBrightness); break;
      case 4: analogWrite(bluePin, blueBrightness); break;
    }
  }

 

Link to comment
Share on other sites

Thank you Mark :)  I remember now - it isn't return - I think it's break to break out of the loop.

Just tested it again with the curly brackets and it made no difference.

Link to comment
Share on other sites

Did what Mark suggested and it's still the same!!  Soon the whole caboodle including PC and monitor is going to be joining the cattle in the next field over the fence!!!!!

Link to comment
Share on other sites

Changed that - uploaded new sketch - still something wrong :(   As I increase the volts all LEDs are off (red should be on) then both red and orange come on, the yellow to join them then green - ie. 4 LEDs on - further increase does nothing.  Blue LED never come on.  When reducing voltage the LEDS don't turn off.  There must be other silly mistakes :(

Link to comment
Share on other sites

Here is the latest sketch.

// Sketch for ATMega328P-PU for Digital Oscilloscope
//
//Looking at discharge curves for Lithium Ion cells and thinking about the voltage levels for each LED.  
//I'm thinking of the following voltage levels :-
//
//    D11 - Blue - Above 4.0v - Fully charged
//    D10 - Green - 3.8-4.0v - Good
//     D9 - Yellow - 3.6-3.8v - Half full
//     D6 - Orange - 3.5-3.6v - Nearly empty
//     D5 - Red - Below 3.5v - STOP, recharge now.
//
//  Cell positive connected to A0 via 3K3 and 1K voltage divider - ratio 4.3:1  ADC using internal 1.1v reference
//  LEDs on D5 D6 D9 D10 D11 - Red Orange Yellow Green Blue
//  LEDs have variable brightness using PWM therefore output with analogWrite(redPin,redBrightness); Brightness variables to be set on test
//
//  ***** Working part starts here *****
//
// Cell discharge voltage presets
int fullVal = 865;
int goodVal = 822;
int midVal = 779;
int lowVal = 757;
//
// LED brightness presets
int redBrightness = 64;
int orangeBrightness = 32;
int yellowBrightness = 50;
int greenBrightness = 255;
int blueBrightness = 16;
//
int cellPin = A0;
int redPin = 5;
int orangePin = 6;
int yellowPin = 9;
int greenPin = 10;
int bluePin = 11;
//
int chargeLevel = 0;
int oldLevel = 0;
//
//
void setup() {
  analogReference(INTERNAL);  // Use internal 1.1v reference for ADC
  pinMode(cellPin,INPUT);   //  cell voltage sensor
  pinMode(redPin, OUTPUT);
  pinMode(orangePin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
// 
// Turn all LEDs off
  analogWrite(redPin,0);
  analogWrite(orangePin,0);
  analogWrite(yellowPin,0);
  analogWrite(greenPin,0);
  analogWrite(bluePin,0);  
}
//
void loop() {
int val = analogRead(cellPin);
//
// set chargeLevel as appropriate depending on val
if (val > fullVal) chargeLevel = 4;
else if (val > goodVal) chargeLevel = 3;
else if (val > midVal) chargeLevel = 2;
else if (val > lowVal) chargeLevel = 1;
else chargeLevel = 0;
//
// Any change??
if (chargeLevel != oldLevel) {
  // chargeLevel has changed so update oldLevel and change LED
  oldLevel = chargeLevel; 
  // turn old LED off
  switch (oldLevel) {
      case 0: { analogWrite(redPin,0); } break;
      case 1: { analogWrite(orangePin,0); } break;
      case 2: { analogWrite(yellowPin,0); } break;
      case 3: { analogWrite(greenPin,0); } break;
      case 4: { analogWrite(bluePin,0); } break;
  }
  //
  // and turn new LED on
  switch (chargeLevel) {
      case 0: {analogWrite(redPin,redBrightness);} break;
      case 1: {analogWrite(orangePin,orangeBrightness);} break;
      case 2: {analogWrite(yellowPin,yellowBrightness);} break;
      case 3: {analogWrite(greenPin,greenBrightness);} break;
      case 4: {analogWrite(bluePin,blueBrightness);} break;
    }
  }
}

 

Link to comment
Share on other sites

You need to change oldlevel AFTER using it to switch the old LED off or you just switch off the one you are about to switch on. ;-)

Quote

if (chargeLevel != oldLevel) {
  // chargeLevel has changed so update oldLevel and change LED
  oldLevel = chargeLevel; 
  // turn old LED off
  switch (oldLevel) {
      case 0: { analogWrite(redPin,0); } break;
      case 1: { analogWrite(orangePin,0); } break;
      case 2: { analogWrite(yellowPin,0); } break;
      case 3: { analogWrite(greenPin,0); } break;
      case 4: { analogWrite(bluePin,0); } break;
  }

 

Link to comment
Share on other sites

Put the oldLevel = chargeLevel in wrong place.  Now corrected.  Also set oldLevel to -1 so that the initial condition of low battery would turn on red LED.  It's working correctly now except that the blue LED still doesn't turn on.

// Sketch for ATMega328P-PU for Digital Oscilloscope
//
//Looking at discharge curves for Lithium Ion cells and thinking about the voltage levels for each LED.  
//I'm thinking of the following voltage levels :-
//
//    D11 - Blue - Above 4.0v - Fully charged
//    D10 - Green - 3.8-4.0v - Good
//     D9 - Yellow - 3.6-3.8v - Half full
//     D6 - Orange - 3.5-3.6v - Nearly empty
//     D5 - Red - Below 3.5v - STOP, recharge now.
//
//  Cell positive connected to A0 via 3K3 and 1K voltage divider - ratio 4.3:1  ADC using internal 1.1v reference
//  LEDs on D5 D6 D9 D10 D11 - Red Orange Yellow Green Blue
//  LEDs have variable brightness using PWM therefore output with analogWrite(redPin,redBrightness); Brightness variables to be set on test
//
//  ***** Working part starts here *****
//
// Cell discharge voltage presets
int fullVal = 865;
int goodVal = 822;
int midVal = 779;
int lowVal = 757;
//
// LED brightness presets
int redBrightness = 64;
int orangeBrightness = 32;
int yellowBrightness = 50;
int greenBrightness = 255;
int blueBrightness = 16;
//
int cellPin = A0;
int redPin = 5;
int orangePin = 6;
int yellowPin = 9;
int greenPin = 10;
int bluePin = 11;
//
int chargeLevel = 0;
int oldLevel = -1; //  oldLevel starts differently from any possible chargeLevel so that initial condition is seen
//                     and a LED is turned on
//
void setup() {
  analogReference(INTERNAL);  // Use internal 1.1v reference for ADC
  pinMode(cellPin,INPUT);   //  cell voltage sensor
  pinMode(redPin, OUTPUT);
  pinMode(orangePin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
// 
// Turn all LEDs off
  analogWrite(redPin,0);
  analogWrite(orangePin,0);
  analogWrite(yellowPin,0);
  analogWrite(greenPin,0);
  analogWrite(bluePin,0);  
}
//
void loop() {
int val = analogRead(cellPin);
//
// set chargeLevel as appropriate depending on val
if (val > fullVal) chargeLevel = 4;
else if (val > goodVal) chargeLevel = 3;
else if (val > midVal) chargeLevel = 2;
else if (val > lowVal) chargeLevel = 1;
else chargeLevel = 0;
//
// Any change??
if (chargeLevel != oldLevel) {
  // chargeLevel has changed so change LED
  // turn old LED off
  switch (oldLevel) {
      case 0: { analogWrite(redPin,0); } break;
      case 1: { analogWrite(orangePin,0); } break;
      case 2: { analogWrite(yellowPin,0); } break;
      case 3: { analogWrite(greenPin,0); } break;
      case 4: { analogWrite(bluePin,0); } break;
  }
  oldLevel = chargeLevel; // update oldLevel 
  //
  // and turn new LED on
  switch (chargeLevel) {
      case 0: {analogWrite(redPin,redBrightness);} break;
      case 1: {analogWrite(orangePin,orangeBrightness);} break;
      case 2: {analogWrite(yellowPin,yellowBrightness);} break;
      case 3: {analogWrite(greenPin,greenBrightness);} break;
      case 4: {analogWrite(bluePin,blueBrightness);} break;
    }
  }
}

 

Link to comment
Share on other sites

Is this actually being assign to 4.  ie greater than 865.  Check by printing  it to serial monitor to see what value val is actually being given by analogRead(cellPin)

36 minutes ago, Gina said:

if (val > fullVal) chargeLevel = 4;

 

 

Link to comment
Share on other sites

Printed out val and chargeLevelval shows sensible values right up to 1023.  chargeLevel changes to 4 between 860 and 870 - voltage control on this cheap PSU is too coarse to tell any closer but that's close enough to prove the point.  All other levels seem right too.  chargeLevel also responds correctly with reducing voltage.  All the LEDs respond correctly except the blue.

Link to comment
Share on other sites

The problem is the ADC  doesn't have a fixed reference unless you turn on the internal 1.1V reference (but then you would need a resistor divider to measure the battery). You need to power your 328 with a stabilised VCC to be able to get accurate repeatable readings from the ADC ports. You are constantly chasing your tail with varying readings currently as the battery discharges.

 

Link to comment
Share on other sites

I have turned on the internal 1.1v reference and have provided a resistor divider so not dependent on Vcc.  Here is the current sketch.

// Sketch for ATMega328P-PU for Digital Oscilloscope
//
//Looking at discharge curves for Lithium Ion cells and thinking about the voltage levels for each LED.  
//I'm thinking of the following voltage levels :-
//
//    D11 - Blue - Above 4.0v - Fully charged
//    D10 - Green - 3.8-4.0v - Good
//     D9 - Yellow - 3.6-3.8v - Half full
//     D6 - Orange - 3.5-3.6v - Nearly empty
//     D5 - Red - Below 3.5v - STOP, recharge now.
//
//  Cell positive connected to A0 via 3K3 and 1K voltage divider - ratio 4.3:1  ADC using internal 1.1v reference
//  LEDs on D5 D6 D9 D10 D11 - Red Orange Yellow Green Blue
//  LEDs have variable brightness using PWM therefore output with analogWrite(redPin,redBrightness); Brightness variables to be set on test
//
//  ***** Working part starts here *****
//
// Cell discharge voltage presets
int fullVal = 865;
int goodVal = 822;
int midVal = 779;
int lowVal = 757;
//
// LED brightness presets
int redBrightness = 64;
int orangeBrightness = 32;
int yellowBrightness = 50;
int greenBrightness = 255;
int blueBrightness = 16;
//
int cellPin = A0;
int redPin = 5;
int orangePin = 6;
int yellowPin = 9;
int greenPin = 10;
int bluePin = 11;
//
int chargeLevel = 0;
int oldLevel = -1; //  oldLevel starts differently from any possible chargeLevel so that initial condition is seen
//                     and a LED is turned on
//
void setup() {
  Serial.begin(9600);
	  analogReference(INTERNAL);  // Use internal 1.1v reference for ADC
  pinMode(cellPin,INPUT);   //  cell voltage sensor
  pinMode(redPin, OUTPUT);
  pinMode(orangePin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
//
// Turn all LEDs off
  analogWrite(redPin,0);
  analogWrite(orangePin,0);
  analogWrite(yellowPin,0);
  analogWrite(greenPin,0);
  analogWrite(bluePin,0);  
}
//
void loop() {
int val = analogRead(cellPin);
  Serial.print(val);
  Serial.print("  ");
  Serial.println(chargeLevel);
	//
// set chargeLevel as appropriate depending on val
if (val > fullVal) chargeLevel = 4;
else if (val > goodVal) chargeLevel = 3;
else if (val > midVal) chargeLevel = 2;
else if (val > lowVal) chargeLevel = 1;
else chargeLevel = 0;
//
// Any change??
if (chargeLevel != oldLevel) {
  // chargeLevel has changed so change LED
  // turn old LED off
  switch (oldLevel) {
      case 0: { analogWrite(redPin,0); } break;
      case 1: { analogWrite(orangePin,0); } break;
      case 2: { analogWrite(yellowPin,0); } break;
      case 3: { analogWrite(greenPin,0); } break;
      case 4: { analogWrite(bluePin,0); } break;
  }
  oldLevel = chargeLevel; // update oldLevel
  //
  // and turn new LED on
  switch (chargeLevel) {
      case 0: {analogWrite(redPin,redBrightness);} break;
      case 1: {analogWrite(orangePin,orangeBrightness);} break;
      case 2: {analogWrite(yellowPin,yellowBrightness);} break;
      case 3: {analogWrite(greenPin,greenBrightness);} break;
      case 4: {analogWrite(bluePin,blueBrightness);} break;
    }
  }
}

Link to comment
Share on other sites

Testing today with the UNO and the LED test sketch and the blue LED has stopped lighting.  The DMM on the UNO pin shows the pin is changing appropriately so the blue LED must have blown.  I'll now test with the battery test sketch.

Link to comment
Share on other sites

It works :)  Uploaded the operational sketch to the UNO and transferred the chip to my battery board.  Connected 0-5v PSU to battery box terminals and all LEDs are working.  Measured the changeover voltages with my DMM and got the following values :- 3.91v, 3.72v, 3.53v, 3.43v.  These will enable me to adjust the chargeLevel values to bring the voltages up to the right value.

int fullVal = 865;  865x4.0/3.91 = 885
int goodVal = 822;  822x3.8/3.72 = 840
int midVal = 779;  779x3.6/3.53 = 794
int lowVal = 757;  757x3.5/3.43 = 772

New code becomes :-
int fullVal = 885;
int goodVal = 840;
int midVal = 794;
int lowVal = 772;

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.