Go Down

Topic: modifying SoftPWM for attiny (Read 5341 times) previous topic - next topic

niekwoo10

Hello,

I would like to be able to use an RGB LED with my attiny45, but it only has 2 PWM ports. I found this SoftwarePWM library http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1268806013.

I tried to compile with the arduino tiny and attiny45 @1Mhz but it didn't work. The library uses timer2.

Is there any way to modify this library for use with attiny45 or another working library?

Coding Badly

Hello,


Hello to you.

Quote
I would like to be able to use an RGB LED with my attiny45, but it only has 2 PWM ports.


It has three.  (technically it has four but two overlap)  I suggest figuring out why the third one is not working rather than trying to port SoftwarePWM.

niekwoo10

I saw on the datasheet that it had 2 channel RGB so i tought 2 pins. Now if i try to fade digital pin 3 it works just fine but with all 3 together the one connected to pd3 just flickers.

niekwoo10

So is there any working software PWM library that's easy to use with attiny45? i only need 1 software PWM port, there are 2 built in harware PWM's in attiny45

Coding Badly


Post your sketch and a link to the core you are using.

niekwoo10

I'm using the arduino tiny core (http://code.google.com/p/arduino-tiny/)

And this is my code:

Code: [Select]

#include <SoftwareSerial.h>

int txPin = 2;

SoftwareSerial sSerial =  SoftwareSerial(36, txPin);

int button = 3;
//Setup the LEDs

// LED outputs
int blueLED = 4;
int redLED = 0;
int greenLED = 1;
int nullLED = 16; // dummy does nothing on this processor attiny45

void setup(){
pinMode(txPin, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(button, INPUT);
   
sSerial.begin(9600);     
}

void loop(){
rainbow(); 
}

void red(){
sSerial.print(1);
digitalWrite(redLED, HIGH);
}

void green(){
sSerial.print(2);
digitalWrite(greenLED, HIGH);   
}

void blue(){
sSerial.print(3);
digitalWrite(blueLED, HIGH);   
}

void none(){
sSerial.print(0);
digitalWrite(redLED, LOW); 
digitalWrite(greenLED, LOW); 
digitalWrite(blueLED, LOW); 
}

void yellow(){ //orange-ish
sSerial.print(4);
analogWrite(redLED, 240); //255
analogWrite(greenLED, 193);
analogWrite(blueLED, 37);
}

void rainbow(){
sSerial.print(5); 
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
      analogWrite(redLED, fadeValue);
      delay(30);   
    }

    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
      analogWrite(redLED, fadeValue);
      delay(30);
    }
   
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
      analogWrite(greenLED, fadeValue);
      delay(30);   
    }
   
    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
      analogWrite(greenLED, fadeValue);
      delay(30);
    }
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
      analogWrite(blueLED, fadeValue);
      delay(30);   
    }
   
    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
      analogWrite(blueLED, fadeValue);
      delay(30);
    }
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
      analogWrite(blueLED, fadeValue);
      analogWrite(redLED, fadeValue);
      analogWrite(greenLED, fadeValue);
      delay(30);   
    }
   
    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
      analogWrite(blueLED, fadeValue);
      analogWrite(redLED, fadeValue);
      analogWrite(greenLED, fadeValue);
      delay(30);
    }
}

   
   
    void violet(){
    sSerial.print(6);
    analogWrite(redLED, 148);
    analogWrite(greenLED, 0);
    analogWrite(blueLED, 211);
    }





So the colors fading one by one works fine, but when they fade together the blue one (witch is not connected to a hardware PWM pin) flickers.

Coding Badly

SoftwareSerial sSerial =  SoftwareSerial( 36, txPin );


http://arduino.cc/forum/index.php/topic,83309.msg626908.html#msg626908

Quote
Do NOT try to access invalid pins.  The Tiny Core (like the Arduino Core) DOES NOT VALIDATE PIN NUMBERS



The core you are using includes "Tiny Debug Serial".  I strongly suggest using Tiny Debug Serial instead of SoftwareSerial.  There are some details available here...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1285218245/25#25

niekwoo10

Oops, typo. I will try to use the Tiny Debug Serial. But i want other attiny45's to receive the message...

Marvin Martian

I'm looking to use this on the ATTINY2313 to PWM all the outputs. I created a new "TinySoftPWM.c/h" library and changed the failing references in blind hope thus

Code: [Select]
  TIFR = (1 << TOV0);          // clear interrupt flag
  TIMSK = (1 << OCIE0A);       // enable timer0 output compare match interrupt
  TCCR0B = (1 << CS01);         // start timer (ck/8 prescalar)
  TCCR0A = (1 << WGM01);        // CTC mode
  OCR0A = SOFTPWM_OCR;


And also changed ISR(TIMER2_COMPA_vect) to ISR(TIMER0_COMPA_vect).

The code now compiles, but behaves oddly once uploaded (TinyISP). I'm running using the internal 8MHz osc so would expect it to be a bit slower, but I seem to be getting some rather random blinking running the SoftPWM blink sketch.
No idea what to try next....

Coding Badly


Marvin Martian

I'm using the Aurduino-Tiny 2313 core.

Made a bit of progress... First realised it was still running at 1Mhz. Burnt the 8MHz bootloader to set the fuses and verified correct speed with the standard blink.

Went back to the SoftPWM blink and it was flickering fast now rather than random blinking. I've since discovered that setting a very long delay between the on and off provides correct functionality i.e.

Code: [Select]
void loop()
{
  SoftPWMSet(5, 255);
  delay(50000);
  SoftPWMSet(5, 0);
  delay(50000);
}

From this I'm concluding that the timer the SoftPWM is now using is also the one the delay() function uses and that has now been changed such that the delay() function no longer provides a delay in ms. I can live with that and just make adjustments in my code. Are there any other side effects I should be aware of?

Coding Badly


Timer 0 is used for millis (delay).  The 2313 has a second timer (timer 1) that is free for you to use.

M1tch3ll

#12
May 10, 2012, 05:15 pm Last Edit: May 10, 2012, 05:24 pm by M1tch3ll Reason: 1
Hi,

I'm working on a project with the ATtiny84 (same cores mentioned above) and the same SoftPWM library.
I tried to change the library according to this:
Quote
I'm looking to use this on the ATTINY2313 to PWM all the outputs. I created a new "TinySoftPWM.c/h" library and changed the failing references in blind hope thus

Code: [Select]
Code:
 TIFR = (1 << TOV0);          // clear interrupt flag
 TIMSK = (1 << OCIE0A);       // enable timer0 output compare match interrupt
 TCCR0B = (1 << CS01);         // start timer (ck/8 prescalar)
 TCCR0A = (1 << WGM01);        // CTC mode
 OCR0A = SOFTPWM_OCR;

And also changed ISR(TIMER2_COMPA_vect) to ISR(TIMER0_COMPA_vect).


The original code in 'SoftPWM_timer.h' was:

Code: [Select]
#if defined(USE_TIMER2)
#define SOFTPWM_TIMER_INTERRUPT    TIMER2_COMPA_vect
#define SOFTPWM_TIMER_SET(val)     (TCNT2 = (val))
#define SOFTPWM_TIMER_INIT(ocr) ({\
 TIFR2 = (1 << TOV2);    /* clear interrupt flag */ \
 TCCR2B = (1 << CS21);   /* start timer (ck/8 prescalar) */ \
 TCCR2A = (1 << WGM21);  /* CTC mode */ \
 OCR2A = (ocr);          /* We want to have at least 30Hz or else it gets choppy */ \
 TIMSK2 = (1 << OCIE2A); /* enable timer2 output compare match interrupt */ \
})


And I changed it to:

Code: [Select]
#if defined(USE_TIMER2)
#define SOFTPWM_TIMER_INTERRUPT    TIMER2_COMPA_vect
#define SOFTPWM_TIMER_SET(val)     (TCNT0 = (val))
#define SOFTPWM_TIMER_INIT(ocr) ({\
 TIFR0 = (1 << TOV0);    /* clear interrupt flag */ \
 TCCR0B = (1 << CS01);   /* start timer (ck/8 prescalar) */ \
 TCCR0A = (1 << WGM01);  /* CTC mode */ \
 OCR0A = SOFTPWM_OCR;          /* We want to have at least 30Hz or else it gets choppy */ \
 TIMSK0 = (1 << OCIE0A); /* enable timer2 output compare match interrupt */ \
})


It compiles and uploads but just doesn't work. It doesn't work when uploaded to my Arduino either so I don't know? It would really be great if someone could help me get this working.

P.S> These are the original compile errors I got before changing the library:
Code: [Select]
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp: In function 'void SoftPWMBegin(uint8_t)':
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'TIFR2' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'TOV2' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'TCCR2B' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'CS21' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'TCCR2A' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'WGM21' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'OCR2A' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'TIMSK2' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:156: error: 'OCIE2A' was not declared in this scope
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp: In function 'void SoftPWMSet(int8_t, uint8_t, uint8_t)':
C:\Users\Mitchell\Documents\Arduino\libraries\SoftPWM\SoftPWM.cpp:205: error: 'TCNT2' was not declared in this scope

Marvin Martian

I managed to get it working on the 2313, and also managed to fix some bugs that prevented output 0 being used as PWM (these have now been fixed in the latest Arduino 1.0 version of SoftPWM I noticed the other day)

Can't remember what I did now - I'll have to re-familiarise myself with teh code again....

I did find that the structures consume a huge amount of RAM - I could only get 8 outputs PWMing and more and really strange things start happening....

vapor20

Marvin-
I, too, am trying to get PWM on a bunch of pins on a 2313.  I've got the code compiling, but would love to find out what you did to make your's work.  Did you ever get a chance to look at your code again and, if so, could you post it? thx

Go Up