system
December 17, 2007, 7:10pm
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
#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
system
December 17, 2007, 7:13pm
2
main.pde
#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();
}
system
December 18, 2007, 5:52pm
3
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!!!
system
December 18, 2007, 6:19pm
4
Ok apparent I'm a moron...
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!