Split from: Problem when porting from MEGA328 to TINY85/TINY13

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello ALL

 

if you are still reading this post, I have found a problem, actually, I cannot  fix it, hence I am posting here.

 

The problem is that when I turn on the light and leave the light on for more than 3 seconds, I cannot turn it off with one hand wiggle, but at least with two! However, if I remove the fading function, for example, I only leave in the turn on and off then I do not face this problem. 

 

Wondering what that could be... maybe it has to do something with the timing, but I am not sure :/

 

any help would be more than helpful,

 BEST.

 

mu234 wrote:

Hello guys, 

 

here it is, sorry that took me so long :P

 

//TINY code

#include <elapsedMillis.h>  //the timer library
#include <TinyWireM.h>        //global library search
#include "Tiny_VCNL4010.h"    //local library search

elapsedMillis timer; //timer
#define shorty 200 // the short interval in mS
#define longy 2000 // the interval in mS
VCNL4010 Sensor; // This is my sensor

//LED PIN
byte ledPin = 1;  // main LED
byte ledSigPin = 4; // signal LED 

//SENSOR THRESHOLDS
volatile uint32_t OS;
volatile uint32_t HT;
volatile uint32_t LT;

//LED (I have three simillar vars, how to optimize this???)
volatile boolean ledOn;     //led state, true is on, false is off
volatile byte ledState;     //led state, true is on, false is off
volatile byte fadeIo;        //do the fade

//PWM table (255) according to (excel formula) : =1/(1+EXP(((A2/21)-6)*-1))*255
byte table[] =
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
  4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10,
  11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 36, 37, 39, 41, 42, 44, 46, 47, 49, 51, 53, 55, 57, 59, 62, 64, 66, 69, 71, 73, 76, 79,
  81, 84, 87, 89, 92, 95, 98, 101, 104, 106, 109, 112, 115, 118, 121, 124, 128, 131, 134, 137, 140, 143, 146, 149, 151, 154, 157, 160, 163, 166,
  168, 171, 174, 176, 179, 182, 184, 186, 189, 191, 193, 196, 198, 200, 202, 204, 206, 208, 209, 211, 213, 214, 216, 218, 219, 221, 222, 223,
  225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 238, 239, 240,
  241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 249,
  250, 250, 250, 250,
  251, 251, 251, 251, 251,
  252, 252, 252, 252, 252, 252, 252,
  253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
  254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255
};

//PWM
volatile byte brightness = 0; // how bright the led is : 4% = cca 10
byte fadeAmount = 1; // fade (pwm) increment

void setup() {
  //Start serial
//  Serial.begin(9600);
//  delay(20);

  //Update the leds on its pin  (ARDUINO PINS !!!)
  // main led
  pinMode(ledPin, OUTPUT);
  // signal led
  pinMode(ledSigPin, OUTPUT);

  //Start the sensor and initialise its values
  delay(300);
  startVCNL();
  delay(2000);

  // set Thresholds
  setT();

  //blink led when rebooted...
  ledBlinkEr(ledSigPin, 5, 5);

  //Serial.println("... and we are ready!");

  //start counting
  timer = 0;
  //led is off
  ledState = 0;
  //the led is off, hence the fadeState = 1 or fade-in
  fadeIo = 1;
}

void loop() {
    if (timer > shorty) {
      if (Sensor.getProximity() >= HT && ledOn == false) {
        ledState = !ledState;
        ledOn = true;
        timer = 0;
      }
    }
    if(timer > 20){   //if sensor prox has dropped and is below LT
      if (Sensor.getProximity() <= HT && Sensor.getProximity() <= LT && ledOn == true ) {
        ledOn = false;
        timer = 0;
      }
    }
    //ON-OFF LED
    // "fade in" function and "turn on" the led
    if (ledState && ledOn == true && fadeIo) {
      fadeIn();
    }
    // "fade out" and turn off the led
    else if (!ledState && ledOn == false && !fadeIo) {
      fadeOut();
    }

    //FADINNG LED
    if (timer > longy) {
      ledState=1;
      if (Sensor.getProximity() >= HT && Sensor.getProximity() > LT) {
        fading();
      }
    }
}  //END OF MAIN LOOP

/////////////////////////// -----> FUNCTIONS <------ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

//FADE-IN (turn on to start from you have left of with fading function)
void fadeIn() {
  //Serial.println("fade-in");
  //go thru the table, start at the zero and go to the end of table
  for (int t = 0; t < brightness; t = t + 3) {   //why I cannot use byte here??
    //Serial.println(t);
    // fade the led with the table values
    analogWrite(ledPin, table[t]);
    //Serial.print("\t"); Serial.println(t);
    delay(6);
  } // end of for loop
  //the led is now on
  analogWrite(ledPin, table[brightness]);
  //led is On, fadeIo = 0, next time we need fade-out, before it was toggle fadeIn =! fadeOut;
  fadeIo = 0;
} //end of "fed in" function and turn on the led

//FADE-OUT (turn on to start from you have left of with fading function)
void fadeOut() {
  //go thru the table, start at the top and go toward zero
  for (int t = brightness; t > 0; t = t - 3) {  //why I cannot use byte here??
    //Serial.println(t);
    // fade the led with the table (1) values
    analogWrite(ledPin, table[t]);
    //Serial.print("\t"); Serial.println(t);
    delay(6);
  } // end of for loop
  analogWrite(ledPin, 0);
  //led is Off, we need fede in next time (fade =1)
  fadeIo = 1;
}

//FADING
void fading() {
  //fade up, if the led is off (brightness is 0), otherwise begin from where it was
  brightness = brightness + fadeAmount;
  //Serial.print("\t"); Serial.print(brightness); Serial.print("\t"); Serial.println(table[brightness]);  //go thru the table and use the value to fade the led
  analogWrite(ledPin, table[brightness]);
  //Serial.print("\t"); Serial.print(brightness);
  if (brightness <= 0 || brightness >= 254) {
    fadeAmount = -fadeAmount;
    if (brightness >= 254) {
      ledBlinkEr(ledPin, 2, 10);
    }
    analogWrite(ledPin, fadeAmount);
  }
  delay(5);  // faking the length of fade
}

// custom led blinker
void ledBlinkEr(byte led, byte times, byte spd) { // poor man's GUI
  for (byte i = 0; i < times; i++) {
    //analog vs. digital?
    analogWrite(led, 255);
    delay ((spd * spd));
    analogWrite(led, 0);
    delay ((spd * spd));
  }
}

// function to initialize the sensor
void startVCNL() {
  //Serial.println(F("Starting VCNL4010 "));
  // Loop until sensor found
  while (!Sensor.begin()) {
    //Show error message
    ledBlinkEr(ledSigPin, 1, 9);
    //Serial.println(F("Error, unable to find or identify VCNL4010."));
    // Wait 2 seconds before retrying
    delay(2000);
  } // of if-then we can't initialize or find the device

  // Boost power to Proximity sensor
  //  20 mA = DEFAULT,
  //  LED Current is limited to 200 mA for values higher.
  Sensor.setLEDmA(200);

  // Sample 128x per second
  //  000 - 1.95 measurements/s (DEFAULT)
  //  001 - 3.90625 measurements/s
  //  010 - 7.8125 measurements/s
  //  011 - 16.625 measurements/s
  //  100 - 31.25 measurements/s
  //  101 - 62.5 measurements/s
  //  110 - 125 measurements/s
  //  111 - 250 measurements/s
  Sensor.setProximityHz(128);     // Sample 128x per second           //

  // Set frequency:
  //  00 = 390.625 kHz (DEFAULT) = 0
  //  01 = 781.25 kHz            = 1
  //  10 = 1.5625 MHz            = 2
  //  11 = 3.125 MHz             = 3
  Sensor.setProximityFreq(0);
  // Continuously sample proximity using frequency and averaging settings
  Sensor.setProximityContinuous(true);
}

// set the thresholds
void setT() {
  //  Serial.println(" Profil measurements... ");
  OS = Sensor.getProximity();
  //Serial.print("\t"); Serial.print(" set OS: "); Serial.print(OS);
  HT = (OS * 102) / 100;  // does this compute correctly ???!!! I can also use with 102, it works, however, than my proxy is lower?! b
  //Serial.print("\t"); Serial.print(" ... "); Serial.print("  HT:"); Serial.println(HT);
  LT = (OS * 101) / 100;  // does this compute correctly ???!!! I can also use with 101, it works, however, than my proxy is lower?!
  //Serial.print("\t"); Serial.print(" ... "); Serial.print("  LT:"); Serial.println(LT);

  // Turnoff continuously reading
  Sensor.setProximityContinuous(false);
  //delay(1000);
}

... and the memory requirements in line with '85'

 

Sketch uses 4060 bytes (49%) of program storage space. Maximum is 8192 bytes.
Global variables use 315 bytes (61%) of dynamic memory, leaving 197 bytes for local variables. Maximum is 512 bytes.

Best.

 

Bravo!!!

Last Edited: Fri. Aug 10, 2018 - 11:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mu234 wrote:
hence I am posting here

Why? 

 

Does it actually have anything to do with the topic of this thread: "Porting from Mega328 to Tiny85/13" ?

 

It seems not - so should be a new thread.

 

EDIT

 

It is now - was just tacked onto the end of https://www.avrfreaks.net/forum/problem-when-porting-mega328-tiny85tiny13

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Aug 10, 2018 - 12:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I look at that code and I have no real idea what is going on. Do you have some kind of design diagram that shows the intended flow of execution?

 

Also this is very confusing:

#define shorty 200 // the short interval in mS
#define longy 2000 // the interval in mS

There is a convention among C/C++ programmers that anything #define'd as a preprocessor macro be given a name in all upper case. That's so that when you later see something like:

    if (timer > shorty) {

it would be clear with:

#define SHORTY 200 // the short interval in mS
#define LONGY 2000 // the interval in mS

and

    if (timer > SHORTY) {

that this is making a comparison against a defined constant - not the comparison of two variables.

 

Also if you are going to have "shorty" and "longy" then in:

    if(timer > 20){   //if sensor prox has dropped and is below LT

shouldn't the 20 here be "very_shorty" for consistency?

 

Anyway I was trying to see what might cause this "3 seconds" effect. As  a timer is involved I guessed it must have something to do with that.

 

Now one thing I don't understand is this code:

    if (timer > shorty) {
      if (Sensor.getProximity() >= HT && ledOn == false) {
        ledState = !ledState;
        ledOn = true;
        timer = 0;
      }
    }
    if(timer > 20){   //if sensor prox has dropped and is below LT
      if (Sensor.getProximity() <= HT && Sensor.getProximity() <= LT && ledOn == true ) {
        ledOn = false;
        timer = 0;
      }
    }

followed later by:

    //FADINNG LED
    if (timer > longy) {
      ledState=1;
      if (Sensor.getProximity() >= HT && Sensor.getProximity() > LT) {
        fading();
      }
    }

It seems to me that there might be quite a strong chance that either of those first two clauses may have led to timer=0 in which case I wonder if it can ever be greater than longy at the execution of the final test?

 

This is why a design diagram (probably a state chart of some kind) would be so useful to explain your planned states of operation. I'm guessing that there is some circumstance in which the system gets into a state that you had not considered and is somehow "stuck" there perhaps?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for split!

 

Best.

Bravo!!!