Hello! I'm trying to drive by pwming one shift register (74HC595) through ATTiny85. The microcontroller gets commands from Arduino through i2c protocol (using TinyWireS library).
Testing i2c standalone succeeds, driving the shift register too, but these two won't run along - while using the leds i2c communication fails.
Probably pwming the leds is interrupting the i2c but I have no idea how to optimize the code to run two time-dependant tasks.
my setup (hardware):
(RESET) = PB5 1 8 VCC = VCC
LATCH = PB3 2 7 PB2 = I2C SCL (ATMega328 - PC5)
CLOCK = PB4 3 6 PB1 = DATA
GND = GND 4 5 PB0 = I2C SDA (ATMega328 - PC4)
here's the code to pwm 74HC595 using timer1:
void timerinit() {
TCCR1 = _BV(CTC1); //clear timer1 when it matches the value in OCR1C
TIMSK |= _BV(OCIE1A); //enable interrupt when OCR1A matches the timer value
// F_CPU = 8Mhz, no divider and all fuses set. 4 is the prescaler, 75 frequency and 256 brightness of the leds
OCR1A = round(((float) F_CPU / (float)4) / ((float)75*((float) 256)) -1); //set the match value for interrupt
OCR1C = round(((float) F_CPU / (float)4) / ((float)75*((float) 256)) -1); //and the same match value to clear the timer
//setting prescaler = 4
bitSet(TCCR1,CS10);
bitSet(TCCR1,CS11);
bitClear(TCCR1,CS12);
sei(); //enable interrupts
}
ISR(TIMER1_COMPA_vect) {
PWMProcess();
}
timerinit() function is called in setup(). PWMProcess is called in every timer interrupt - setting leds on and off very fast.
void PWMProcess(){
byte PWMsrVals; // here we have temporary array of SR values
PWMticker++;
// TICKER_PWM_LEVELS is defined as 32, TICKER_STEP is defined as 256/TICKER_PWM_LEVELS
if(PWMticker > TICKER_PWM_LEVELS) PWMticker = 0;
// get ticker as a 0 to 255 value, so we can always use the same data regardless of actual PWM levels
int myPos = PWMticker * TICKER_STEP;
// Loop through all bits in the shift register
for (int i = 0 ; i < 8; i++ ){
int myLev = 1;
if (PWMsrPins[i] > myPos) myLev = 0;
bitWrite(PWMsrVals, i, myLev);
}
bitClear(PORTB, LATCHPIN); // setting the latch off
shiftOut(DATAPIN, CLOCKPIN, LSBFIRST, PWMsrVals); // setting the SR
bitSet(PORTB, LATCHPIN); // setting the latch on
}
I guess the PWMProcess() function may be the bottleneck and needs optimization, could you give me any tips how to do this?
Underline: how to run correctly time-dependant task (i2c) and clock-consuming task (pwm) so they don't bother eachother?