Arduino to ATtiny85 Help

Hi I have been using the Arduino to read a brass Adafruit flow meter to measure water flow and then to conditionally close a valve and wanted to switch this over to the ATtiny85 and I am having issues doing so. The code for the flow meter requires use of TIMSK0 and TIMER0 in the code and the ATtiny gets an error message saying that TIMSK0 isn't defined. I looked up in the ATtiny85's datasheet to find that there is only one timer (TIMSK) and I switched the name of TIMER0 to that but still cannot get the conditional statements to work using the ATtiny85 as they were with the Arduino. If anyone has any ideas or help it would be much appreciated.

jengil:
I looked up in the ATtiny85's datasheet to find that there is only one timer (TIMSK)

The ATtiny85 has two timers, but only one TIMSK register which has bits for both Timer0 and Timer1. Therefore, TIMSK bits are different than the ATmega328 TIMSK0, so you'll need different bit masks. The datasheet should tell you what bits need to be set (pg 81).

I took a quick glance and it looks like the control register bits (TCCR0A, TCCR0B) are the same ATtiny85 vs ATmega328, but if you still have problems do take a closer look to make sure.

Thanks so much for the response, that is very helpful although I don't know how my program calls those bits.

In my original (Uno) code things look like this

SIGNAL(TIMER0_COMPA_vect) {
uint8_t x = digitalRead(FLOWSENSORPIN);

and then farther down it calls the interrupt:

void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK |= _BV(OCIE0A);
} else {
// do not call the interrupt function COMPA anymore
TIMSK &= ~_BV(OCIE0A);
}

I noticed that the OCIE0A has the same Location as the TOIE0 for the Tiny and tried using that instead with no luck. Forgive my lack on programming experience but how can I gt the Tiny to read those bits properly? Thanks again

"_BV" stands for "Bit Value".

The "&= ~" construct clears a bit (which usually disables something).

The "|=" construct sets a bit (which usually enables something).

OCIE0A enables/disables the Timer0 compare match A and TOIE0 enables/disables the Timer0 overflow. Which you need to use depends on what you're trying to do, in this case it looks like the comments refer to the compare match. I have no experience with the Adafruit flow meter, unfortunately, so I'm not sure where you need to go from here. What you have looks correct?

As for "OCR0A = 0xAF;", I rarely see hex in Arduino code. I would instead write that as "OCROA = 175;" which I find is much easier to understand.

Once again, thank you very much. I am actually just using the code that is for the flow meter so I am not 100% sure what it is doing or how it works, although I know its using Compare and TIMSK0. Here's a link for the original code (which I have modified to make TIMSK0 --> TIMSK and also commented out all of the serial/lcd prints. I feel like I am close but have yet to figure it out.

If you have any suggestions as to what else I would need to change to address the bit correctly it would be very helpful. Thanks!

Hmm. I think you are addressing the bits correctly. However, I'm not familiar with this naming convention:

SIGNAL(TIMER0_COMPA_vect)

In my own code, I use:

ISR(TIM0_COMPA_vect)

This change might be worth a try?

Also, what Core are you using? I use Google Code Archive - Long-term storage for Google Code Project Hosting. so I'm not familiar with the HLT or other Cores.

I am not too familiar with the core which I am using is there a good way to determine it? also i tried your code change with the ISR and it compiles and uploads fine but still cannot get it to work with the flow sensor. It makes it difficult that I cannot see the results on the serial monitor like with the Uno. I think it may just have to be in the TIMSK lines or the OCR0A line. As you can see on the datasheets below, the OCIE0A registers have different bits, but I still don't know how to reference them correctly.

^page 110

^page 81

Hmm.. I'll keep looking through - I guess just let me know if you have any methods or ideas of calling those registers or getting this to work on the tiny85. Thank you.

Regarding TIMER0_COMPA_vect vs. TIM0_COMPA_vect, unfortunately:

  1. Atmel does not use a consistent name across different processors. The processor datasheet gives the interrupt vector names.

  2. If you use the wrong name for the processor you are compiling for, gcc only emits a warning message, not an error;

  3. The designers of the Arduino IDE made the disgraceful decision to suppress all warning messages by default (perhaps in order to hide all the warnings from the Arduino core libraries).

So the first thing you need to do is to go to File->Preferences and turn on verbose compilation messages. Then look for warning messages when your own file is compiled.

Personally, I prefer not to use an Arduino core when compiling for the attiny85 family, I use Atmel Studio instead.

Thank you - I turned on verbose compilation messages and managed to find a variety of errors that are coming up, most of which I cannot make any sense of and do not tell me much (since I don't understand the stuff very well). Is there any way to interpret these errors? many look like a bunch of directories followed by things like Arduino.h:193 or Stream.cpp:23 or Hardware Serial.h:28 . Any advice on how to debug would be much appreciated. Thanks again.

You can ignore the warnings generated in those files, they are caused by poor coding in the core libraries. Look for warnings generated when your own files are compiled, which will be right at the start of the output. Try compiling the code without uploading, because if you upload as well, the message buffer will probably become full and the messages from the start of the job will get discarded.

Excellent using the ISR code it seems to work, it just seems like it is not metering accurate amounts. There may need to be conversions from running at the 16MHz clock (Uno) to now on the tiny's 8MHz clock. For instance I am trying to open a switch when 0.3 liters have passed through the flow meter, and I have to actually pass through approximately 5.7 liters before it turns off. Any suggestions there? Thanks

The difference between 8MHz and 16MHz operation should be taken care of by the F_CPU parameter defined in the board definition. So, unless you have an incorrect board definition, that doesn't explain the problem. Did you clear the CLKDIV8 fuse bit? If not, then your attiny will be running at 1MHz, not 8MHz.

No, I did not clear that bit and am not sure that I know how to do so. Is there any way to get this tiny to run at 16MHz? I simply cannot figure out why none of the numbers are correct. Thanks!

What are you using to program the attiny85?

I am using the Arduino environment. I just tried using someone elses changed fuse code in the boards.txt and apparently it's running at 16 MHz (I cant test it without a scope) but my numbers are still off. For instance I get 1.3 liters of flow for what is supposed to be 0.01 liters. These numbers do not seem to change when I go back between 1 and 8 MHz either. I am unsure where any of this miscommunication is coming from.

jengil:
I am using the Arduino environment. I just tried using someone elses changed fuse code in the boards.txt and apparently it's running at 16 MHz (I cant test it without a scope)

If you have correctly set the fuses to use an external crystal, and you have a 16MHz crystal connected between the XTAL1 and XTAL2 pins of the attiny85 along with the required 18pF or 22pF capacitors to ground, then it should be running at 16MHz. Otherwise, it's definitely not running at 16MHz. EDIT: see the next post - it seems theren is another way of clocking it at 16MHz.

What do you mean by "I am using the Arduino environment"? How did you upload the program to the attiny, and how did you change the fuses?

The ATtiny85 can run at 16MHz clocked from the internal 64MHz PLL divided by four. It's a bit of an odd duck among the ATtiny line, none of the others have this PLL, that I'm aware of.

As for setting the clock speed, you must select the appropriate entry in the Boards menu and then use the Burn Bootloader function. You won't actually burn a bootloader, that's just what you have to do to burn the fuses on an ATtiny85 using the Arduino IDE. Simply "uploading" does NOT set any fuses.

Here's the boards.txt entry that I use:

attiny85at16p.name=ATtiny85 @ 16 MHz (internal PLL; 4.3 V BOD)

# The following do NOT work...
# attiny85at16p.upload.using=avrispv2
# attiny85at16p.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny85at16p.upload.using=arduino:arduinoisp
# attiny85at16p.upload.protocol=avrispv2
# attiny85at16p.upload.using=pololu

attiny85at16p.upload.maximum_size=8192

# PLL Clock; Start-up time PWRDWN/RESET: 1K CK/14 CK + 4 ms; [CKSEL=0001 SUT=00]
# Brown-out detection level at VCC=4.3 V; [BODLEVEL=100]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]
# Serial program downloading (SPI) enabled; [SPIEN=0]

attiny85at16p.bootloader.low_fuses=0xC1
attiny85at16p.bootloader.high_fuses=0xD4
attiny85at16p.bootloader.extended_fuses=0xFF
attiny85at16p.bootloader.path=empty
attiny85at16p.bootloader.file=empty85at16.hex

attiny85at16p.build.mcu=attiny85
attiny85at16p.build.f_cpu=16000000L
attiny85at16p.build.core=tiny

Thanks for the replies everyone. I am programming it using a sparkfun programmer, and it wont burn the bootloader with that code added to the boards.txt, also it has errors. I found another set of code elsewhere for burning the bootloader and it works but the tiny still does not count the pulses properly, Not sure if it will work or not...

heres a boards file as well, this is how the fuses are being manipulated.

attiny45.name=ATtiny45 (internal 1 MHz clock)
attiny45.bootloader.low_fuses=0x62
attiny45.bootloader.high_fuses=0xdf
attiny45.bootloader.extended_fuses=0xff
attiny45.upload.maximum_size=4096
attiny45.build.mcu=attiny45
attiny45.build.f_cpu=1000000L
attiny45.build.core=arduino:arduino
attiny45.build.variant=tiny8

attiny45-8.name=ATtiny45 (internal 8 MHz clock)




attiny45-8.bootloader.low_fuses=0xe2
attiny45-8.bootloader.high_fuses=0xdf
attiny45-8.bootloader.extended_fuses=0xff
attiny45-8.upload.maximum_size=4096
attiny45-8.build.mcu=attiny45
attiny45-8.build.f_cpu=8000000L
attiny45-8.build.core=arduino:arduino
attiny45-8.build.variant=tiny8

attiny45-20.name=ATtiny45 (external 20 MHz clock)

-attiny85-8.name=ATtiny45 (internal 16 MHz PLL clock)
 -attiny85-8.bootloader.low_fuses=0xe2
 -attiny85-8.bootloader.high_fuses=0xdf
 -attiny85-8.bootloader.extended_fuses=0xff
 -attiny85-8.upload.maximum_size=4096
 -attiny85-8.build.mcu=attiny85
 -attiny85-8.build.f_cpu=16000000L
 -attiny85-8.build.core=arduino:arduino
 -attiny85-8.build.variant=tiny8
+attiny45-16.name=ATtiny45 (internal 16 MHz PLL clock)
 +attiny45-16.bootloader.low_fuses=0x71
 +attiny45-16.bootloader.high_fuses=0xdf
 +attiny45-16.bootloader.extended_fuses=0xff
 +attiny45-16.upload.maximum_size=4096
 +attiny45-16.build.mcu=attiny85
 +attiny45-16.build.f_cpu=16000000L
 +attiny45-16.build.core=arduino:arduino
 +attiny45-16.build.variant=tiny8


attiny45-20.bootloader.low_fuses=0xfe
attiny45-20.bootloader.high_fuses=0xdf
attiny45-20.bootloader.extended_fuses=0xff
attiny45-20.upload.maximum_size=4096
attiny45-20.build.mcu=attiny45
attiny45-20.build.f_cpu=20000000L
attiny45-20.build.core=arduino:arduino
attiny45-20.build.variant=tiny8

attiny85.name=ATtiny85 (internal 1 MHz clock)
attiny85.bootloader.low_fuses=0x62
attiny85.bootloader.high_fuses=0xdf
attiny85.bootloader.extended_fuses=0xff
attiny85.upload.maximum_size=8192
attiny85.build.mcu=attiny85
attiny85.build.f_cpu=1000000L
attiny85.build.core=arduino:arduino
attiny85.build.variant=tiny8

attiny85-8.name=ATtiny85 (internal 8 MHz clock)
attiny85-8.bootloader.low_fuses=0xe2
attiny85-8.bootloader.high_fuses=0xdf
attiny85-8.bootloader.extended_fuses=0xff
attiny85-8.upload.maximum_size=8192
attiny85-8.build.mcu=attiny85
attiny85-8.build.f_cpu=8000000L
attiny85-8.build.core=arduino:arduino
attiny85-8.build.variant=tiny8

-attiny85-8.name=ATtiny85 (internal 16 MHz PLL clock)
 -attiny85-8.bootloader.low_fuses=0xe2
 -attiny85-8.bootloader.high_fuses=0xdf
 -attiny85-8.bootloader.extended_fuses=0xff
 -attiny85-8.upload.maximum_size=8192
 -attiny85-8.build.mcu=attiny85
 -attiny85-8.build.f_cpu=16000000L
 -attiny85-8.build.core=arduino:arduino
 -attiny85-8.build.variant=tiny8
 +attiny85-16.name=ATtiny85 (internal 16 MHz PLL clock)
 +attiny85-16.bootloader.low_fuses=0x71
 +attiny85-16.bootloader.high_fuses=0xdf
 +attiny85-16.bootloader.extended_fuses=0xff
 +attiny85-16.upload.maximum_size=8192
 +attiny85-16.build.mcu=attiny85
 +attiny85-16.build.f_cpu=16000000L
 +attiny85-16.build.core=arduino:arduino
 +attiny85-16.build.variant=tiny8



attiny85-20.name=ATtiny85 (external 20 MHz clock)
attiny85-20.bootloader.low_fuses=0xfe
attiny85-20.bootloader.high_fuses=0xdf
attiny85-20.bootloader.extended_fuses=0xff
attiny85-20.upload.maximum_size=8192
attiny85-20.build.mcu=attiny85
attiny85-20.build.f_cpu=20000000L
attiny85-20.build.core=arduino:arduino
attiny85-20.build.variant=tiny8

attiny44.name=ATtiny44 (internal 1 MHz clock)
attiny44.bootloader.low_fuses=0x62
attiny44.bootloader.high_fuses=0xdf
attiny44.bootloader.extended_fuses=0xff
attiny44.upload.maximum_size=4096
attiny44.build.mcu=attiny44
attiny44.build.f_cpu=1000000L
attiny44.build.core=arduino:arduino
attiny44.build.variant=tiny14

attiny44-8.name=ATtiny44 (internal 8 MHz clock)
attiny44-8.bootloader.low_fuses=0xe2
attiny44-8.bootloader.high_fuses=0xdf
attiny44-8.bootloader.extended_fuses=0xff
attiny44-8.upload.maximum_size=4096
attiny44-8.build.mcu=attiny44
attiny44-8.build.f_cpu=8000000L
attiny44-8.build.core=arduino:arduino
attiny44-8.build.variant=tiny14

attiny44-20.name=ATtiny44 (external 20 MHz clock)
attiny44-20.bootloader.low_fuses=0xfe
attiny44-20.bootloader.high_fuses=0xdf
attiny44-20.bootloader.extended_fuses=0xff
attiny44-20.upload.maximum_size=4096
attiny44-20.build.mcu=attiny44
attiny44-20.build.f_cpu=20000000L
attiny44-20.build.core=arduino:arduino
attiny44-20.build.variant=tiny14

attiny84.name=ATtiny84 (internal 1 MHz clock)
attiny84.bootloader.low_fuses=0x62
attiny84.bootloader.high_fuses=0xdf
attiny84.bootloader.extended_fuses=0xff
attiny84.upload.maximum_size=8192
attiny84.build.mcu=attiny84
attiny84.build.f_cpu=1000000L
attiny84.build.core=arduino:arduino
attiny84.build.variant=tiny14

attiny84-8.name=ATtiny84 (internal 8 MHz clock)
attiny84-8.bootloader.low_fuses=0xe2
attiny84-8.bootloader.high_fuses=0xdf
attiny84-8.bootloader.extended_fuses=0xff
attiny84-8.upload.maximum_size=8192
attiny84-8.build.mcu=attiny84
attiny84-8.build.f_cpu=8000000L
attiny84-8.build.core=arduino:arduino
attiny84-8.build.variant=tiny14

attiny84-20.name=ATtiny84 (external 20 MHz clock)
attiny84-20.bootloader.low_fuses=0xfe
attiny84-20.bootloader.high_fuses=0xdf
attiny84-20.bootloader.extended_fuses=0xff
attiny84-20.upload.maximum_size=8192
attiny84-20.build.mcu=attiny84
attiny84-20.build.f_cpu=20000000L
attiny84-20.build.core=arduino:arduino
attiny84-20.build.variant=tiny14