ATtiny85 sketch won't compile because of delay()

I have a simple sketch that compiles and works on my UNO but trying to compile on the tiny core for an ATtiny85 microcontroller fails at delay commands.

The sketch

// High/Low microsecond timings, first value is high timing, the rest alternate low/high
const int hlUsTimings[] = {
    380,440,700,800,360,440,720,780,380,440,700,800,360,460,700,780,380,440,700,800,360,800,360,460,720,13000};
const int x = sizeof(hlUsTimings) / sizeof(hlUsTimings[0]);

const int pinChangeDelay = 17;                    // Value to subtract from numbers to compensate for instruction timings
const int outPin = 3;                             // Transmitter output pin
const int ledPin = 4;                             // LED output pin

void setup() {
    pinMode(ledPin,OUTPUT);
    pinMode(outPin,OUTPUT);
    digitalWrite(outPin,LOW);
    delayMicroseconds(12000);
}

void loop() {
    digitalWrite(ledPin,HIGH);
    byte pinState = 0;
    for (int y = 0; y < x; y++){
        pinState = !pinState;
        digitalWrite(outPin,pinState);
        int z = hlUsTimings[y] - pinChangeDelay;
        delayMicroseconds(z);
    }
    digitalWrite(ledPin,LOW);
}

The error

In file included from sketch_jul04a.ino:2:
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DDR_Z" requires 4 arguments, but only 1 given
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_PIN_Z" requires 4 arguments, but only 1 given
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_PORT_Z" requires 4 arguments, but only 1 given
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIDR_Z" requires 4 arguments, but only 1 given
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIO_BIT_Z" requires 4 arguments, but only 1 given
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIO_TIMER_Z" requires 4 arguments, but only 1 given
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIO_CHANNEL_Z" requires 4 arguments, but only 1 given
In file included from sketch_jul04a.ino:2:
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DDR_Z' was not declared in this scope
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_PIN_Z' was not declared in this scope
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_PORT_Z' was not declared in this scope
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIDR_Z' was not declared in this scope
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIO_BIT_Z' was not declared in this scope
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIO_TIMER_Z' was not declared in this scope
D:\Shared_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIO_CHANNEL_Z' was not declared in this scope
sketch_jul04a.ino: In function 'void setup()':
sketch_jul04a:14: error: 'delayMicroseconds' was not declared in this scope
sketch_jul04a.ino: In function 'void loop()':
sketch_jul04a:24: error: 'delayMicroseconds' was not declared in this scope

Is delay() & delayMicroseconds() not supported on tiny core?

Where does it say anything about "delay()"?

Use these: avr-libc: <util/delay.h>: Convenience functions for busy-wait delay loops

fungus:
Where does it say anything about "delay()"?

Use these: avr-libc: <util/delay.h>: Convenience functions for busy-wait delay loops

It errors on both delay() and delayMicroseconds()
I did include util/delay.h and try to use _delay_us but it also flagged errors (cannot remember what they were now).
I downloaded the HLT tiny core and it compiles fine so downloaded the correct/older arduino-tiny core and it also compiles fine so will stick with it instead of the newer core.

Out of interest I notice the digitalWrite for both working cores takes 40uS less to set a pin low than setting it high but the UNO version the high/low change takes about the same time. I had to add an extra 40uS delay after setting pin low in the loop to get timings to match array.

http://forum.arduino.cc/index.php?topic=173408.0

Tiny Core 2 is ready (enough) for human consumption.

What I meant by "ready (enough)" is that the new version is incomplete. I can see now that was not worded well. Sorry about the confusion.

If you have a request, please post it here. More requests = higher priority.

[quote author=Coding Badly link=topic=175628.msg1303725#msg1303725 date=1372961800]

http://forum.arduino.cc/index.php?topic=173408.0

Tiny Core 2 is ready (enough) for human consumption.

What I meant by "ready (enough)" is that the new version is incomplete. I can see now that was not worded well. Sorry about the confusion.[/quote]

Oops, I had never seen the thread you link to. I just went straight to code.google for the latest core when I deleted my old one by mistake. Should I request support for delay & delayMicroseconds in that thread? Unless I screwed up in programming then even _delay_us does not work so there is no easy workaround that I know of.

Riva:
Should I request support for delay & delayMicroseconds in that thread?

I looked again but I still can't see where it says "delay()" in here:

In file included from sketch_jul04a.ino:2:
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DDR_Z" requires 4 arguments, but only 1 given
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_PIN_Z" requires 4 arguments, but only 1 given
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_PORT_Z" requires 4 arguments, but only 1 given
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIDR_Z" requires 4 arguments, but only 1 given
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIO_BIT_Z" requires 4 arguments, but only 1 given
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIO_TIMER_Z" requires 4 arguments, but only 1 given
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663:28: error: macro "TC_DIO_CHANNEL_Z" requires 4 arguments, but only 1 given
In file included from sketch_jul04a.ino:2:
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DDR_Z' was not declared in this scope
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_PIN_Z' was not declared in this scope
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_PORT_Z' was not declared in this scope
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIDR_Z' was not declared in this scope
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIO_BIT_Z' was not declared in this scope
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIO_TIMER_Z' was not declared in this scope
D:\Shared\_arduino-1.0.5_Tiny\hardware\arduino\cores\tiny/Arduino.h:663: error: 'TC_DIO_CHANNEL_Z' was not declared in this scope
sketch_jul04a.ino: In function 'void setup()':
sketch_jul04a:14: error: 'delayMicroseconds' was not declared in this scope
sketch_jul04a.ino: In function 'void loop()':
sketch_jul04a:24: error: 'delayMicroseconds' was not declared in this scope

fungus:
I looked again but I still can't see where it says "delay()" in here:

Doesn't matter. delay is not yet in the new core.

Riva:
Oops, I had never seen the thread you link to. I just went straight to code.google for the latest core when I deleted my old one by mistake.

I'm impressed you found the new version. You may be the only person on the planet who actually goes to the Downloads tab. The majority uses a link from the Project Home tab, a direct external link, or Git / SVN. I added "Alpha" and "Incomplete" labels to make it more clear what it is.

Should I request support for delay & delayMicroseconds in that thread?

Are you working with an ATtiny861 processor? If no, then make the request here (and let me know which processor / board you are using).

Unless I screwed up in programming then even _delay_us does not work so there is no easy workaround that I know of.

For the ATtiny861 processor I added a parameter to an internal macro set. Support for the other processors just needs to be brought up-to-date. That's what all the "TC_*_Z" errors are. Once that's resolved, _delay_us and _delay_ms will work fine. And, adding support for delay and delayMicroseconds will be next on the list.

[quote author=Coding Badly link=topic=175628.msg1303889#msg1303889 date=1372970163]
I'm impressed you found the new version. You may be the only person on the planet who actually goes to the Downloads tab. The majority uses a link from the Project Home tab, a direct external link, or Git / SVN. I added "Alpha" and "Incomplete" labels to make it more clear what it is.
As the saying goes "It is impossible to make anything idiot-proof because idiots are such ingenious people" :smiley:

Should I request support for delay & delayMicroseconds in that thread?

Are you working with an ATtiny861 processor? If no, then make the request here (and let me know which processor / board you are using).
I'm using a tiny85 on a home grown board.

Unless I screwed up in programming then even _delay_us does not work so there is no easy workaround that I know of.

For the ATtiny861 processor I added a parameter to an internal macro set. Support for the other processors just needs to be brought up-to-date. That's what all the "TC_*_Z" errors are. Once that's resolved, _delay_us and _delay_ms will work fine. And, adding support for delay and delayMicroseconds will be next on the list.
Thanks Coding Badly. The old core works fine for what I need so don't adjust your schedule to do this as I have what I need for now. [/quote]
I am still interested in why it takes 40uS less time to do digitalWrite(pin, LOW) on both tiny cores I tried (yours and HLT) compared to the UNO core. The UNO core seems to take about the same time to set a pin HIGH as it does LOW but the tiny is different timings so makes time critical pin changes slightly more challenging.

fungus:

Riva:
Should I request support for delay & delayMicroseconds in that thread?

I looked again but I still can't see where it says "delay()" in here:

As stated in previous post "It errors on both delay() and delayMicroseconds()". The error log I posted happened to be for delayMicroseconds(). I have changed the subject title to match.

Riva:
I am still interested in why it takes 40uS less time to do digitalWrite(pin, LOW) on both tiny cores I tried (yours and HLT) compared to the UNO core.

digitalWrite is very similar between the three and the code path for LOW and HIGH should be almost identical. I just checked... As far as I can tell there should be one machine instruction more for the LOW path; certainly not 40uS.

There is a difference between PWM pins and non-PWM pins on all three cores.

The UNO core seems to take about the same time to set a pin HIGH as it does LOW but the tiny is different timings so makes time critical pin changes slightly more challenging.

Just so you know, there really isn't an HLT core. It's the standard core with a pin mapping for tiny processors. There really cannot be a difference between an Uno and a tiny using the HLT core.

If you have a test case, I'm willing to research the problem.

[quote author=Coding Badly link=topic=175628.msg1304356#msg1304356 date=1373016126]
If you have a test case, I'm willing to research the problem.[/quote]
At work yesterday I was getting a consistent 40uS timing difference between LOW/HIGH pin changes so adjusted the code to add in extra 40uS delay to get the signal to match. I forgot that the code was changing 2x pins so the difference between HIGH/LOW would really be about 20uS. At home today with slight code changes it's still about 20uS. This could be due to analyser jitter and/or interrupts as some timings match expected values.

Here is my test code

// High/Low microsecond timings, first value is high timing, the rest alternate low/high
const int hlUsTimings[] = {
380,440,700,800,360,440,720,780,380,440,700,800,360,460,700,780,380,440,700,800,360,800,360,460,720,13000};
const int hlUsSize = sizeof(hlUsTimings) / sizeof(hlUsTimings[0]);

const int pinChangeDelay = 17;                    // Value to subtract from numbers to compensate for instruction timings
const int outPin = 3;                             // Transmitter output pin
const int ledPin = 4;                             // LED output pin

void setup() {
  pinMode(ledPin,OUTPUT);
  pinMode(outPin,OUTPUT);
  digitalWrite(outPin,LOW);
  delayMicroseconds(13000);
}

void loop() {
  digitalWrite(ledPin,!digitalRead(ledPin));
  byte pinState = 0;
  for (int y = 0; y < hlUsSize; y++){
    pinState = !pinState;
    digitalWrite(outPin,pinState);
    // if (pinState == 0){
      // delayMicroseconds(20);
    // }
    int z = hlUsTimings[y] - pinChangeDelay;
    delayMicroseconds(z);
  }
}

Channel 1 is the original signal capture, channel 2 is the UNO output and channel 3 is the tiny85 output
It's probably not worth deeper investigation but let me know and I can do more tests.

Riva:
This could be due to analyser jitter and/or interrupts as some timings match expected values.

Could also be the millis interrupt service routine interfering. Try this...

// High/Low microsecond timings, first value is high timing, the rest alternate low/high
const int hlUsTimings[] = {
380,440,700,800,360,440,720,780,380,440,700,800,360,460,700,780,380,440,700,800,360,800,360,460,720,13000};
const int hlUsSize = sizeof(hlUsTimings) / sizeof(hlUsTimings[0]);

const int pinChangeDelay = 17;                    // Value to subtract from numbers to compensate for instruction timings
const int outPin = 3;                             // Transmitter output pin
const int ledPin = 4;                             // LED output pin

void setup() {
  pinMode(ledPin,OUTPUT);
  pinMode(outPin,OUTPUT);
  digitalWrite(outPin,LOW);
  delayMicroseconds(13000);
}

void loop() {
  digitalWrite(ledPin,!digitalRead(ledPin));
  byte pinState = 0;
  noInterrupts();
  for (int y = 0; y < hlUsSize; y++){
    pinState = !pinState;
    digitalWrite(outPin,pinState);
    // if (pinState == 0){
      // delayMicroseconds(20);
    // }
    int z = hlUsTimings[y] - pinChangeDelay;
    delayMicroseconds(z);
  }
  interrupts();
}

Disabling interrupts helped so much I could zero pinChangeDelay and the trace almost perfectly matches the UNO one that did have pinChangeDelay = 17. Not sure why this should be though? I'm sure the thing is close enough now and will test it later today on the receiver.

// High/Low microsecond timings, first value is high timing, the rest alternate low/high
const int hlUsTimings[] = {
380,440,700,800,360,440,720,780,380,440,700,800,360,460,700,780,380,440,700,800,360,800,360,460,720,13000};
const int hlUsSize = sizeof(hlUsTimings) / sizeof(hlUsTimings[0]);

const int pinChangeDelay = 0;                     // Value to subtract from numbers to compensate for instruction timings
const int outPin = 3;                             // Transmitter output pin
const int ledPin = 4;                             // LED output pin

void setup() {
  pinMode(ledPin,OUTPUT);
  pinMode(outPin,OUTPUT);
  digitalWrite(outPin,LOW);
  delayMicroseconds(13000);
}

void loop() {
  digitalWrite(ledPin,!digitalRead(ledPin));
  byte pinState = 0;
  noInterrupts();
  for (int y = 0; y < hlUsSize; y++){
    pinState = !pinState;
    digitalWrite(outPin,pinState);
    // if (pinState == 0){
      // delayMicroseconds(20);
    // }
    int z = hlUsTimings[y] - pinChangeDelay;
    delayMicroseconds(z);
  }
  interrupts();
}

Riva:
Not sure why this should be though?

It's what I said in the reply above. The millis timer is interrupting your code which is interfering with your code's timing.

The Uno and t85 behave differently because they are running at different clock speeds. The interrupt service routine interferes less on the Uno simply because it runs twice as fast.

You're not actually using millis, micros, or delay so the timer could actually be shut off.

That t85 is surprisingly accurate.

[quote author=Coding Badly link=topic=175628.msg1305530#msg1305530 date=1373100449]
That t85 is surprisingly accurate.[/quote]
Well I went to the coastal property and tested the thing yesterday and it worked a treat so now we can have a gate entry remote in both cars. No more forgotten remote and a hefty parking fee. Just need to box it up now.
Thanks for your help.

Riva:
The 'not sure why' was in reference to removing the 17uS delay applied to all values to compensate for the time the code need to run through the loop each time. It's 17uS in the UNO trace but I reduced it to 0uS on the tiny.

You seem to be pleased so I'm not going to pursue it beyond offering one wild speculation: delayMicroseconds has some compensation to try to make it more accurate. Maybe that part of delayMicroseconds is a bit short which nicely compensates for your code.

How is the delayMicroseconds() timing derived?

It's essentially a for-loop.

Riva:
Well I went to the coastal property and tested the thing yesterday and it worked a treat so now we can have a gate entry remote in both cars. No more forgotten remote and a hefty parking fee. Just need to box it up now.

Nice.

Thanks for your help.

You are welcome.