Go Down

Topic: Issue with PWM and delay() (Read 1 time) previous topic - next topic

xSmurf

Dec 17, 2007, 08:10 pm Last Edit: Dec 17, 2007, 08:13 pm by xSmurf Reason: 1
Hello, I'm writing this simple PWM led controller program and it looks like whenever I start using analogWrite(), the delay() function stops working. I'm using a breaboard version of the arduino with the internal osc. set at 8Mhz (with no divider) with a makefile (both CPU_FREQ and F_CPU are set at 8000000 using -D). Fuses are set as such: L:0xE2, H:0xDD, E:0xFF (0x07 for  avrdude not to mess up).

I really don't get it Ô.o

Any ideas?

Here's the code
main.h
Code: [Select]
#ifndef _MAIN_H_
#define _MAIN_H_
     
     /**
      * Pin definitions
     **/
     #define pinRearLight            9
     #define pinFrontLight            10
     #define pinSettingBtn            8
     
     /**
      * Dim level definitions
     **/
     #define dimLevel0                  255
     #define dimLevel1                  190
     #define dimLevel2                  125
     #define dimLevel3                  63
     #define dimLevel4                  0
     #define dimLevelDefault            dimLevel1
     
     // High/low ratio
     #define dimLevelLow                  0.66
     
     // Setting button debounce interval
     #define bounceInterval            50
     
     /**
      * Variable declarations
     **/
     uint16_t previousMillis, previousMillisSettingBtn;
     uint8_t rearLightInterval, rearLightValue, readLightIncrement;
     
     boolean settingBtnVal            = false;
     boolean settingBtnLastVal      = false;
     int8_t bounceTime                  = 0;
     int8_t settingBtnPhase            = -1;
     
     boolean breakStatus                  = false;
     uint8_t rearBlinkPhase            = 0;
     
     boolean frontHighState            = false;
     uint8_t frontDimLevel            = 0;
     
     /**
      * Prototypes
     **/
     void rearLightOff(void);
     void rearLightOn(void);
     void writeDimLevel(void);
     void readDimLevel(void);
     void changeFrontHighStatus(void);
     void setFrontLight(void);
     void changeBreakStatus(void);
     
#endif /* End of Main.h */


main.pde to follow
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

xSmurf

#1
Dec 17, 2007, 08:13 pm Last Edit: Dec 17, 2007, 08:14 pm by xSmurf Reason: 1
main.pde

Code: [Select]
#include <avr/eeprom.h>
#include <avr/wdt.h>

#include "main.h"

/**
     todo: display battery status
**/

void rearLightOff(void)
{
     digitalWrite(pinRearLight, HIGH);
}

void rearLightOn(void)
{
     analogWrite(pinRearLight, dimLevelDefault);
}

void changeBreakStatus(void)
{
     breakStatus != breakStatus;
     
     if (breakStatus) {
           rearLightOn();
     } else {
           rearBlinkPhase            = 0;
     }
     
     return;
}

void setFrontLight(void)
{
     // Set the front led output
     if (frontHighState) analogWrite(pinFrontLight, frontDimLevel);
     // Set front led output in low state
     else analogWrite(pinFrontLight, (uint8_t) (dimLevel0 - (dimLevel0 - frontDimLevel) * dimLevelLow));
     
     return;
}

void changeFrontHighStatus(void)
{
     frontHighState != frontHighState;
     
     setFrontLight();
     
     return;
}

void readDimLevel(void)
{
     uint8_t eepromValue = 0;
     
     // Wait for the eeprom to be ready
     while (!eeprom_is_ready());
     
     eepromValue = eeprom_read_byte(0);
     
     frontDimLevel      = eepromValue;
     
     return;
}

void writeDimLevel(void)
{      
     // Wait for the eeprom to be ready
     while (!eeprom_is_ready());
     
     eeprom_write_byte(0, frontDimLevel);
     
     return;
}

void setup(void)
{
     
     // Set pin modes
     pinMode(pinRearLight, OUTPUT);
     pinMode(pinFrontLight, OUTPUT);
     pinMode(pinSettingBtn, INPUT);
     
     // Attach external interrupts
     attachInterrupt(0, changeBreakStatus, CHANGE);
     attachInterrupt(1, changeFrontHighStatus, CHANGE);
     
     // Read the previous dim level
     readDimLevel();
     
     // Set the front light on
     setFrontLight();
     
     // Enable watchdog
//       wdt_reset();
// #ifdef WDTO_4S
//       wdt_enable(WDTO_4S);
// #else
//       wdt_enable(WDTO_2S);
// #endif
}

void loop(void)
{
     /**
      * START settings routine
     **/
     /*
     settingBtnVal = digitalRead(pinSettingBtn);
     
     if (bounceTime == -1 && settingBtnVal == HIGH) {
           bounceTime = 0;
     }

     if (settingBtnVal == LOW && settingBtnLastVal == LOW) {
           bounceTime++;
           if (bounceTime >= bounceInterval) {
                 bounceTime = -1;
                 settingBtnVal = HIGH;
           }
     }
     
     if (settingBtnVal == HIGH && settingBtnLastVal == LOW) {
           settingBtnLastVal = HIGH;
           settingBtnPhase++;
           previousMillisSettingBtn = millis();
     }
     
     if (settingBtnVal == LOW && settingBtnLastVal == HIGH && bounceTime != -1) {
           settingBtnLastVal = LOW;
     }
     
     if (millis() - previousMillisSettingBtn < 1000 && settingBtnPhase >= 0)
     {
           if (settingBtnPhase == 0)
           {
                 frontDimLevel = dimLevel4;
           }
           
           if (settingBtnPhase == 1)
           {
                 frontDimLevel = dimLevel3;
           }
           
           if (settingBtnPhase == 2)
           {
                 frontDimLevel = dimLevel2;
           }
           
           if (settingBtnPhase == 3)
           {
                 frontDimLevel = dimLevel1;
           }
           
           if (settingBtnPhase == 4)
           {
                 frontDimLevel = dimLevel0;
           }
           
           if (settingBtnPhase == 5)
           {
                 settingBtnPhase = -1;
           } else {
                 writeDimLevel();
                 setFrontLight();
           }
     } else {
           settingBtnPhase = -1;
     }
     */
     // END settings

     // Throbbing back led routine
     if (!breakStatus && settingBtnPhase == -1) {
           if (rearBlinkPhase == 0)
           {
                 for (readLightIncrement=255;readLightIncrement>=0;readLightIncrement--)
                 {
                       analogWrite(pinRearLight, readLightIncrement);
                       delay(1);
                 }
                 
                 rearLightOn();
                 
                 previousMillis = millis();
           
                 rearBlinkPhase++;
           }
           else if (rearBlinkPhase == 1) {
                 if (millis() - previousMillis > 5000)
                 {
                       rearBlinkPhase++;
                 }
           }
           else if (rearBlinkPhase == 2) {
                 for (readLightIncrement=0;readLightIncrement<256;readLightIncrement++)
                 {
                       analogWrite(pinRearLight, readLightIncrement);
                       delay(2);
                 }
                 
                 rearLightOff();
                 
                 previousMillis = millis();
           
                 rearBlinkPhase++;
           }
           else if (rearBlinkPhase == 3){
                 if (millis() - previousMillis > 5000)
                 {
                       rearBlinkPhase = 0;
                 }
           }
     }

     // Reset the watchdog timer
     //wdt_reset();
}

"Pilots believe in a clean living... they never drink wisky from a dirty glass."

xSmurf

#2
Dec 18, 2007, 06:52 pm Last Edit: Dec 18, 2007, 07:05 pm by xSmurf Reason: 1
I've just tested it and I get the same behavior on the Arduino board (using both 0009 and 0010!) :S

EDIT: Ok serial also seems to stop working when I start the PWM!!!
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

xSmurf

Ok apparent I'm a moron...

Code: [Select]
for (rearLightIncrement=255;rearLightIncrement>=0;rearLightIncrement--)
     {
           analogWrite(pinRearLight, rearLightIncrement);
           delay(10);
     }


since I had >=0 when it go to zero is seems like it tried to take one away again and that messed up the whole thing!
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy