Ported working prog from Arduino board to attiny85, not working

Seeking some advise and pointers on how to analyze and fix my program, which worked as expected on Arduino (Duemillanove), but once ported to ATtiny85, doesn't work any more.
My program decodes an ISM band (315MHz/433MHz) ASK/OOK, proprietary encoded signal on the MCU, using INT0 (external interrput), and based on detection of all transitions (high to low and low to high edges).

Some of the key differences, I can tell, are:

  1. Arduino has XTAL (and thus higher precision) clock @ 16MHz, but my ATtiny is running at 8MHz using internal oscillator. My program is quite sensitive to timing, however, on Arduino, I use the standard Arduino micros() function, to determine valid (versus noise) RF signals and do the decoding, i.e. identify valid waveform vs noise. However on ATtiny85 side, I still use Arduino-Tiny, with the F_CPU rightly set (well, I trust Arduino IDE to do that for me, since I've the right Board type set), and fuse-bits blown accordingly (i.e. burn bootloader done). So, I think I am good on this part, i.e. shouldn't be an issue.

  2. Pins used have obviously changed. On Arduino I was using DigitalWriteFast (user-contributed) library, that makes usage of digital Pins significantly faster compared to Arduino's standard lib for same. However, I couldn't get DigitalWriteFast to work on ATtiny85, so I made my own function, that directly uses DDRB, PORTB, PINB, with right set of masks. I've tested those functions of setting pin mode to OUTPUT/INPUT, and setting pin value HIGH/LOW etc., separately in a simple program, and they work fine. So I am ruling this aspect out (for the moment).

  3. Since I depend on INT0 external interrupt, I am dependent on Arduino-tiny's support (i.e. correct implementation) for that via attachInterrupt(0,...) , and the RF data source is indeed connected to Pin#7 (INT0) on ATtiny85.

I am positive that the LED's on the outpin pins are wired up correctly. I've tested those using test program on exact same MCU using the direct port manipulation method (DDRB, PORTB... settings), and they work fine.

So I am at loss, as to what might be going wrong. Some obvious guesses (which I find tad hard to justify though) are --

A) The difference in clock is hurting me somehow on ATtiny85
B) INT0 interrupt handling in Arduino-Tiny isn't exactly correct, or maybe it's usage is bit different in ATtiny85.
C) Anything else... ?

Oh BTW, I do not have a DSO, but have a fairly functional OpenBench "Sump" LogicAnalyzer, so my troubleshooting tools are kind-of limited. Since I do not have a FTDI breakout board either, I can use Serial.print().

Thanks in anticipation.

One thing to remember is that the internal RC oscillator is factory calibrated at 3.0V and 25°C. Running at 5V or a different temperature will get you a different clock speed.

You can re-calibrate the clock at the voltage and temperature you are using. You will need an accurate time signal, such as a 1Hz signal from an RTC chip. A sketch that measures the pulse length in microseconds can then adjust the RC oscillator by setting the OSCCAL register.

Thanks @johnwasser. I guess, I've hit the limits of my knowledge of AVRs, but taking a hint from "clock recalibration", I did recollect having seen a tool on Arduino-Tiny google-code page, that might do something similar. It is called TinyTuner. It requires something that can pump in 'x' accurately at 9600bps into the target attiny85, on pin#0. The program does seem to update OSCCAL in the end. Could you confirm if this is something that could be useful in my situation ?

Can I use an Arduino to pump 'x's into the target attiny, at 9600bps. I guess, it should be possible, accurately enough. Some examples, or pointers to existing schematic for this purpose with help. BTW, at the moment I do not have an RTC IC, but will get one if there is no other way.

The more I read of TinyTimer, the more I am certain that indeed it does what was recommended by you, @johnwasser.

CodingBadly has not only done a great job of writing that software, but also documenting it darn well -- very important for n00bs like me.

I found some easy/simple to follow instructions in: TinyTuner/examples/Save_to_EEPROM/Save_to_EEPROM.pde file, specific to attiny85.

Will try this out. Thanks @johnwasser, and @CodingBadly. Will report back on how it goes.

If you have an older Duemilanove or Diecimila you might want to use that instead of the UNO. They have a quartz crystal oscillator rather than the somewhat less precise resonator on the UNO.

@johnwasser, I do have a Duemilanove with the quartz crystal. However at the moment, I’ve very little idea, how I can use that, to do this caliberation. I mean, what would the physical connectivity between Arduino and the target ATtiny be like.

BTW, I’ve started another thread regarding the wiring-up required for TinyTuner.

falcon74:
@johnwasser, I do have a Duemilanove with the quartz crystal. However at the moment, I've very little idea, how I can use that, to do this caliberation. I mean, what would the physical connectivity between Arduino and the target ATtiny be like.

BTW, I've started another thread regarding the wiring-up required for TinyTuner.

I'm guessing the serial TX pin (Pin 1) of the Arduino goes to Pin 0 of the ATtiny. And the Ground pin of the Arduino connects to the Ground pin of the ATtiny.

Awaiting some further clarity on how exactly to hook up, I improvised (I think), but the results aren't very encouraging.

What I did was to write a small program that just toggles a pin, and does delayMicroseconds(1000) sleep, and toggle pin again. Then I attach my OLS logic-sniffer and measure the frequency of the entire capture. Without OSCCAL set, I notice a frequency of 501Hz. So I went ahead and introduced OSCCAL=0x60. Now the frequency dropped to 427MHz. Then I set OSCCAL=0x70, and frequncy became 478MHz. Then I tried used several iterations to try and narrow down the OSCCAL value to match frequency of 500Hz, however this didn't succeed, as with --

OCSCCAL = 0x75, frequency I get is 503, and with OSCCAL=0x74, the frequency I got is 497Hz, which means, that for no value of OSCCAL can I get precise 500Hz, and that effectively without user-caliberation of, the factory calibration is good enough. Thay thoughts, anyone ?

First, some general information about OSCCAL and the internal oscillator…

• For most processors, the range is split across 128. In other words, the ideal value can be between 0 and 127 or between 128 and 255.

• The ideal value is not necessarily in the range selected by the OSCCAL factory value.

• According to the documentation, large changes can cause the processor to temporarily behave erratically. Adjust the value by +1 or -1 at a time followed by a very tiny time delay.

• Atmel only guarantees ±1%. In my experience, ±0.25% is often achievable.

• OSCAL changes do not always produce the expected frequency change. For example, it is possible that 0x73 may produce a slightly higher frequency than 0x74. You should always check the next two OSCAL values…

0x75 503
0x74 497
0x73 498

• The internal oscillator is dependent on temperature.

• The internal oscillator is dependent on voltage.

• The internal oscillator has a tiny amount of jitter but, for a given voltage and temperature, the average frequency seems stable.

Now for @falcon74’s questions…

What I did was to write a small program that just toggles a pin, and does delayMicroseconds(1000) sleep, and toggle pin again.

You need to implement this using “blink without delay” or you will have to account for the instruction overhead. In addition, the millis timer will occasionally fire and interfere with your measurements.

OCSCCAL = 0x75, frequency I get is 503

(503 - 500) / 500 = 0.6%. That may be as good as you are going to get.

@CodingBadly, thanks for explaining this.

While reading the data-sheet, to understand more about OSCCAL and I did see the 2 ranges split but wasn't 100% clear on what it achieves, thanks to your explanation now I understand. I also did notice that the graphs were non-linear (somewhat expected).

Had forgotten about BlinkWithoutDelay and I had been redirected to it, for a very similar reason earlier. Will certainly try my experiement with it. However, wondering if I can use something like the SoftSerial + MAX232 to interface with laptop's Serial-USB converter, to try out the sketch within TinyTuner ?

As per my current (not-so-accurate) logic though, with factory defaults, I remember clocking around 501Hz, which is then effectively very good accuracy of 0.2%. I forgot to note the OSCCAL value when factory set. I will see what it is. However, I am thinking that it might be a good idea to stagger around that value itself, right ? Both in the lower and upper ranges.

If this doesn't work, I plan to try with a XTAL to see if that helps. My algorithms (my original program) have 5% timing tolerance built-in, so I guess the clock frequency shouldn't be an issue. Wonder what else could be going wrong ?

falcon74:
However, wondering if I can use something like the SoftSerial + MAX232 to interface with laptop's Serial-USB converter, to try out the sketch within TinyTuner ?

Let's work through Tiny Tuner on the other topic.

However, I am thinking that it might be a good idea to stagger around that value itself, right ?

That's essentially how Tiny Tuner works. The factory value is the starting point and it hunts in either direction for something more accurate.

Tiny Tuner does not check the other range. I assumed that the Atmel folks picked a particular range for a reason and that it is best to hunt within that range. My assumption about hunting within just one range could easily be wrong.

My program is quite sensitive to timing, however, on Arduino, I use the standard Arduino micros() function, to determine valid (versus noise) RF signals and do the decoding, i.e. identify valid waveform vs noise. ... As per my current (not-so-accurate) logic though, with factory defaults, I remember clocking around 501Hz, which is then effectively very good accuracy of 0.2%. ... My algorithms (my original program) have 5% timing tolerance built-in, so I guess the clock frequency shouldn't be an issue. Wonder what else could be going wrong ?

The granularity of micros is 4 when the processor is running at 16 MHz and 8 when the processor is running at 8 MHz. Could the much courser granularity cause a problem?

Fair enough.

Up to, 40us worth of variation is tolerated by my program.