Help! Unsupported CPU Frequency in timer1.h

Trying to use a Teensy to control a force sensor and the #Include <Timer1.h> library seems to be throwing an error:

Here is the error
Documents\Arduino\libraries\Timer1/Timer1.h:65:6: error: #error ("Unsupported CPU frequency")

65 | #error("Unsupported CPU frequency")

In the timer library, this is the if/else statement where I believe it's occuring:

#include <inttypes.h>

// 16.9.6 TIMSK0 – Timer/Counter Interrupt Mask Register (page 134)
#ifndef disableMillis
#define disableMillis() TIMSK0 &= ~1
#endif
#ifndef enableMillis
#define enableMillis() TIMSK0 |= 1
#endif
#ifndef microsFromCounting
#if (F_CPU == 16000000L)
#define microsFromCounting(COUNTING) ((COUNTING) << 2)
#elif (F_CPU == 8000000L)
#define microsFromCounting(COUNTING) ((COUNTING) << 3)
#else
#error("Unsupported CPU frequency")
#endif
#endif
#ifndef microsFromSlowCounting
#if (F_CPU == 16000000L)
#define microsFromSlowCounting(SLOWCOUNTING) ((SLOWCOUNTING) << 4)
#elif (F_CPU == 8000000L)
#define microsFromSlowCounting(SLOWCOUNTING) ((SLOWCOUNTING) << 5)
#else
#error("Unsupported CPU frequency")
#endif
#endif

Not sure where to begin here and please help!

What Arduino board are you using ? Uno, Nano, something else ?

Also try running this sketch and say what result it delivers:

void setup() {
   delay( 1000 ) ;
   Serial.begin( 9600 ) ;
   Serial.println( F_CPU ) ;
}

void loop() { }

EDIT

If that does not work, try the standard blink sketch in the IDE. It should blink at a rate of 1 second on and 1 second off. Try to estimate what the actual times are if these appear to be different to those which are expected.

Which one? The MCUs used in the 3.x and 4.x Teensies don't have AVR Timers like the Arduino Uno.

I am trying to use a Teensy 4.1

That library is intended for AVR processors and won't work for the Teensy 4.1.

What are you trying to do with the Teensy 4.1?

I am trying to connect these sensors: [Easy to Use, Accurate, Miniature Force Sensors — SingleTact](Single Tact Sensor)

They have an associated library to get them to run: github singletact but this didnt work with my Arduino Mega or my Teensy. Not sure what I can do to get this running!

Please identify or post a link to the exact sensor you are trying to use.

Also, post the complete code example that produces the error messages. Please use code tags when posting code.

Hello, I'm having the same problem as the original poster. I'm working with an Arduino UNO R4 Wifi board and this sensor : Capteur de force calibré de 8mm de diamètre, 10N/2.2lb - SingleTact.
The company SingleTact provides a library to include and a sketch to compile before using their data acquisition software, it can be found at : GitHub - SingleTact/WinAppArduinoInterface: A simple arduino interface to interact with the SingleTact App (see Quick Start Guide https://www.singletact.com/resources/) and here it is :

//-----------------------------------------------------------------------------
//  Copyright (c) 2015 Pressure Profile Systems
//
//  Licensed under the MIT license. This file may not be copied, modified, or
//  distributed except according to those terms.
//-----------------------------------------------------------------------------

#include <Wire.h> //For I2C/SMBus
#include <Timer1.h> //For timestamp

#define CMD_READ        0x01
#define CMD_WRITE       0x02
#define CMD_TOGGLE_GPIO 0x03
#define CMD_WRITE_CAL   0x04
#define TOGGLE_ALL      0x08
#define TOGGLE_NONE     0x00

//Constants
//General I2C packet structure
const byte I2C_HEADER1 = 0;
const byte I2C_HEADER2 = 1;
const byte I2C_HEADER3 = 2;
const byte I2C_HEADER4 = 3;
const byte I2C_ADDRESS_BYTE = 4;
const byte I2C_TIMOUT_BYTE = 5;
const byte I2C_ID_BYTE = 6;
const byte I2C_NUM_FOOTER_BYTES = 4;
const byte I2C_TO_SENSOR_BUFFER_LENGTH = 32;
const byte I2C_TIMEOUT = 100; //100ms

//From PC
const byte I2C_FROMPC_CMD = 7;
const byte I2C_FROMPC_READWRITE_LOCATION = 8;
const byte I2C_FROMPC_NUM_BYTES_TO_READWRITE = 9;
const byte SERIAL_FROMPC_BUFFER_LENGTH = 43;
const byte MINIMUM_FROMPC_PACKETLENGTH = 13; //I2C_FROMPC_NUM_BYTES_TO_READWRITE + 4 footer bytes

//To PC
const byte I2C_TOPC_TIMESTAMP = 7;
const byte I2C_TOPC_NBYTES = 11;
const byte SERIAL_TOPC_BUFFER_LENGTH = 77;

// Pin 13 has an LED connected.
int led = 13;

// Pin 2, 3, 4, 5, 6, 7 are reserved for Power Line
int singleTact1 = 2;
int singleTact2 = 3;
int singleTact3 = 4;
int singleTact4 = 5;
int singleTact5 = 6;
int singleTact6 = 7;

//From Arduino to sensor
byte outgoingI2CBuffer[I2C_TO_SENSOR_BUFFER_LENGTH];

//From Arduino to PC host
byte serialToPCBuffer[SERIAL_TOPC_BUFFER_LENGTH];
byte serialToPCBufferIndex_ = 0;

//From PC host to Arduino
byte serialIncomingBuffer[SERIAL_FROMPC_BUFFER_LENGTH];
byte serialIncomingBufferIndex_ = 0;

unsigned long timeStamp_;

//Zero a buffer
void BlankBuffer(byte* buffer, byte length)
{
  for(int i = 0; i < length; i++)
  {
    buffer[i] = 0;
  }
}

void ResetSerialBuffer()
{
  for(int i = 0; i < SERIAL_FROMPC_BUFFER_LENGTH; i++)
  {
    serialIncomingBuffer[i] = 0;
  }

  serialIncomingBufferIndex_ = 0;
}

void setup()
{
  int i;

  Wire.begin(); // join i2c bus (address optional for master)

  pinMode(led, OUTPUT);
  Serial.begin(115200);  // start serial for output
  Serial.flush();

  pinMode(singleTact1, OUTPUT);
  pinMode(singleTact2, OUTPUT);
  pinMode(singleTact3, OUTPUT);
  pinMode(singleTact4, OUTPUT);
  pinMode(singleTact5, OUTPUT);
  pinMode(singleTact6, OUTPUT);

  BlankBuffer(outgoingI2CBuffer, I2C_TO_SENSOR_BUFFER_LENGTH);

  //Never changes, so just set now
  serialToPCBuffer[I2C_HEADER1] = 0xFF;
  serialToPCBuffer[I2C_HEADER2] = 0xFF;
  serialToPCBuffer[I2C_HEADER3] = 0xFF;
  serialToPCBuffer[I2C_HEADER4] = 0xFF;

  digitalWrite(led, HIGH);

  timeStamp_ = 0;
  startTimer1(100); //Timer for timestamp
}


//Check the full footer
boolean Checkfooter(int endOfPacket)
{
  for(int i = 0; i < 4; i++)
  {
    if(serialIncomingBuffer[endOfPacket - i] != 0xFE)
    {
      return false;  //Footer corrupt
    }
  }

  return true; //Footer all good
}


//Check available header bytes (called as each one comes in, building upto 4)
boolean Checkheader(int checkMaxIndex)
{
  for(int j = 0; j <= checkMaxIndex && j < 4; j ++)
  {
    if(serialIncomingBuffer[j] != 0xFF)
    {
      return false; //Header corrupt
    }
  }
  return true; //Header all good
}

//Returns true if we have a new serial data packet, otherwise returns false
//Corrupt data is removed from buffer
boolean ProcessIncomingSerialData()
{
  byte i2cPacketLength; //Working variable

  if(Serial.available() > 0)
  {
    //Read the new byte
    serialIncomingBuffer[serialIncomingBufferIndex_] = Serial.read();
  }
  else
  {
    //No new data
    return false;
  }

  if(false == Checkheader(serialIncomingBufferIndex_))
  {
    ResetSerialBuffer();  //Header not correct, reset buffer
    return false;
  }

  //Do we have enough data to process
  if(serialIncomingBufferIndex_ >MINIMUM_FROMPC_PACKETLENGTH)
  {
    if(CMD_READ == serialIncomingBuffer[I2C_FROMPC_CMD])
    {
      i2cPacketLength = 0;
    }
    else
    {
      i2cPacketLength = serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE];
    }


    //Do we have a full packet
    if(serialIncomingBufferIndex_ >= (i2cPacketLength + MINIMUM_FROMPC_PACKETLENGTH + 1))
    {
      if(Checkfooter(serialIncomingBufferIndex_))
      {
        //We have a good packet
        return true;
      }
      else
      {
        //Corrupt packet, reset
        ResetSerialBuffer();
        return false;
      }
    }
  }

  //We have run out of buffer space - something has gone wrong, so just reset the buffer
  if(serialIncomingBufferIndex_ >= (SERIAL_FROMPC_BUFFER_LENGTH -1))
  {
    ResetSerialBuffer();
  }

  serialIncomingBufferIndex_++; //Move the index on
  return false;  //Not at the end of the packet yet
}

// Define the function which will handle the notifications
ISR(timer1Event)
{
  resetTimer1();
  timeStamp_++;
}

void loop()
{
  byte inputBuffer[43];
  byte finishedPacket = false;
  byte timeout = 5;
  byte i = 0;
  byte lengthReceived = 0;

  if(ProcessIncomingSerialData())
  {
    if(CMD_WRITE == serialIncomingBuffer[I2C_FROMPC_CMD])
    {
      //We are changing settings
      if(serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE] > 0)
      {
        //Create return packet for the PC
        serialToPCBuffer[I2C_ADDRESS_BYTE] = serialIncomingBuffer[I2C_ADDRESS_BYTE];
        serialToPCBuffer[I2C_TIMOUT_BYTE] = 0; //We did not timeout
        serialToPCBuffer[I2C_ID_BYTE] = serialIncomingBuffer[I2C_ID_BYTE];
        serialToPCBuffer[I2C_TOPC_NBYTES] = 0; //No data, just ack

        serialToPCBuffer[I2C_TOPC_NBYTES+1] = 0xFE;
        serialToPCBuffer[I2C_TOPC_NBYTES+2] = 0xFE;
        serialToPCBuffer[I2C_TOPC_NBYTES+3] = 0xFE;
        serialToPCBuffer[I2C_TOPC_NBYTES+4] = 0xFE;

        //Transfer data
        for(int i = 0; i < serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE]+4; i++)
        outgoingI2CBuffer[i] = serialIncomingBuffer[i+I2C_FROMPC_CMD];

        //Send I2C packet
        Wire.beginTransmission(serialIncomingBuffer[I2C_ADDRESS_BYTE]); // transmit to device
        Wire.write(outgoingI2CBuffer, I2C_TO_SENSOR_BUFFER_LENGTH);
        Wire.endTransmission();    // stop transmitting

        //Send serial ack to PC
        for(int i = 0; i < (I2C_TOPC_NBYTES+5); i++)
        Serial.write(serialToPCBuffer[i]);
      }
    }
    else if(CMD_READ == serialIncomingBuffer[I2C_FROMPC_CMD])
    {
      byte i2cPacketLength = serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE];

      serialToPCBuffer[I2C_ADDRESS_BYTE] = serialIncomingBuffer[I2C_ADDRESS_BYTE];
      serialToPCBuffer[I2C_TIMOUT_BYTE] = 0;
      serialToPCBuffer[I2C_ID_BYTE] = serialIncomingBuffer[I2C_ID_BYTE];
      serialToPCBuffer[I2C_TOPC_NBYTES] = i2cPacketLength;

      serialToPCBuffer[I2C_TOPC_TIMESTAMP] = (timeStamp_ >> 24);
      serialToPCBuffer[I2C_TOPC_TIMESTAMP + 1 ] = (timeStamp_ >> 16) & 0xFF;
      serialToPCBuffer[I2C_TOPC_TIMESTAMP + 2 ] = (timeStamp_ >> 8) & 0xFF;
      serialToPCBuffer[I2C_TOPC_TIMESTAMP + 3 ] = timeStamp_ & 0xFF;

      //Perform I2C Read
      outgoingI2CBuffer[0] = CMD_READ;
      outgoingI2CBuffer[1] = serialIncomingBuffer[I2C_FROMPC_READWRITE_LOCATION];
      outgoingI2CBuffer[2] = serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE];

      //Send I2C packet
      Wire.beginTransmission(serialIncomingBuffer[I2C_ADDRESS_BYTE]); // transmit to device
      Wire.write(outgoingI2CBuffer, 3); //Only requires 3 bytes
      Wire.endTransmission();    // stop transmitting

      Wire.requestFrom(serialIncomingBuffer[I2C_ADDRESS_BYTE], serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE]);

      //Parse request
      int i = 0;
      int i2cTimeout = I2C_TIMEOUT; //1s

      while( i < i2cPacketLength && i2cTimeout > 0)    // slave may send less than requested
      {
        if(Wire.available())
        {
          serialToPCBuffer[I2C_TOPC_NBYTES + 1 + i] = Wire.read(); // receive a byte as character
          i++;
        }
        else
        {
          delay(1); //Wait 1ms
          i2cTimeout--;
        }
      }

      if(0 == timeout)
      {
        serialToPCBuffer[I2C_TIMOUT_BYTE] = 1;
      }

      //Add footer
      serialToPCBuffer[I2C_TOPC_NBYTES + 1 + i2cPacketLength] = 0xFE;
      serialToPCBuffer[I2C_TOPC_NBYTES + 2 + i2cPacketLength] = 0xFE;
      serialToPCBuffer[I2C_TOPC_NBYTES + 3 + i2cPacketLength] = 0xFE;
      serialToPCBuffer[I2C_TOPC_NBYTES + 4 + i2cPacketLength] = 0xFE;

      //Send to PC
      for(int i = 0; i < (I2C_TOPC_NBYTES + 5 + i2cPacketLength); i++)
      Serial.write(serialToPCBuffer[i]);
    }

    // Transmit the Calibration Data to the Interface Board
    if(CMD_WRITE_CAL == serialIncomingBuffer[I2C_FROMPC_CMD])
    {
      //We are changing settings
      if(serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE] > 0)
      {
        //Create return packet for the PC
        serialToPCBuffer[I2C_ADDRESS_BYTE] = serialIncomingBuffer[I2C_ADDRESS_BYTE];
        serialToPCBuffer[I2C_TIMOUT_BYTE] = 0; //We did not timeout
        serialToPCBuffer[I2C_ID_BYTE] = serialIncomingBuffer[I2C_ID_BYTE];
        serialToPCBuffer[I2C_TOPC_NBYTES] = 0; //No data, just ack

        serialToPCBuffer[I2C_TOPC_NBYTES+1] = 0xFE;
        serialToPCBuffer[I2C_TOPC_NBYTES+2] = 0xFE;
        serialToPCBuffer[I2C_TOPC_NBYTES+3] = 0xFE;
        serialToPCBuffer[I2C_TOPC_NBYTES+4] = 0xFE;

        //Transfer data
        for(int i = 0; i < serialIncomingBuffer[I2C_FROMPC_NUM_BYTES_TO_READWRITE]+4; i++)
        {
          outgoingI2CBuffer[i] = serialIncomingBuffer[i+I2C_FROMPC_CMD];
        }

        //Send I2C packet
        Wire.beginTransmission(serialIncomingBuffer[I2C_ADDRESS_BYTE]); // transmit to device
        Wire.write(outgoingI2CBuffer, I2C_TO_SENSOR_BUFFER_LENGTH);
        Wire.endTransmission();    // stop transmitting

        //Send serial ack to PC
        for(int i = 0; i < (I2C_TOPC_NBYTES+5); i++)
        {
          Serial.write(serialToPCBuffer[i]);
        }
      }

    }
    // Toggle the GPIO Pin to set the I2C address when doing Calibration test
    else if (CMD_TOGGLE_GPIO == serialIncomingBuffer[I2C_FROMPC_CMD])
    {
      serialToPCBuffer[I2C_ADDRESS_BYTE] = serialIncomingBuffer[I2C_ADDRESS_BYTE];
      serialToPCBuffer[I2C_TIMOUT_BYTE] = 0; //We did not timeout
      serialToPCBuffer[I2C_ID_BYTE] = serialIncomingBuffer[I2C_ID_BYTE];
      serialToPCBuffer[I2C_TOPC_NBYTES] = 0; //No data, just ack

      int toggle = serialToPCBuffer[I2C_FROMPC_CMD+1];
      if (TOGGLE_ALL == serialIncomingBuffer[I2C_FROMPC_CMD+1])
      {
        digitalWrite(singleTact1, HIGH);
        digitalWrite(singleTact2, HIGH);
        digitalWrite(singleTact3, HIGH);
        digitalWrite(singleTact4, HIGH);
        digitalWrite(singleTact5, HIGH);
        digitalWrite(singleTact6, HIGH);
      }
      else if (TOGGLE_NONE == serialIncomingBuffer[I2C_FROMPC_CMD+1])
      {
        digitalWrite(singleTact1, LOW);
        digitalWrite(singleTact2, LOW);
        digitalWrite(singleTact3, LOW);
        digitalWrite(singleTact4, LOW);
        digitalWrite(singleTact5, LOW);
        digitalWrite(singleTact6, LOW);
        Wire.endTransmission();
        delay(50);
        Wire.begin();
      }
      else
      {
        digitalWrite(singleTact1, LOW);
        digitalWrite(singleTact2, LOW);
        digitalWrite(singleTact3, LOW);
        digitalWrite(singleTact4, LOW);
        digitalWrite(singleTact5, LOW);
        digitalWrite(singleTact6, LOW);
        digitalWrite(serialIncomingBuffer[I2C_FROMPC_CMD+1], HIGH);
      }

      serialToPCBuffer[I2C_TOPC_NBYTES+1] = 0xFE;
      serialToPCBuffer[I2C_TOPC_NBYTES+2] = 0xFE;
      serialToPCBuffer[I2C_TOPC_NBYTES+3] = 0xFE;
      serialToPCBuffer[I2C_TOPC_NBYTES+4] = 0xFE;

      //Send serial ack to PC
      for(int i = 0; i < (I2C_TOPC_NBYTES+5); i++)
      {
        Serial.write(serialToPCBuffer[i]);
      }
    }

    ResetSerialBuffer();  //Reset and wait for next command
  }
}

While trying to compile this on my board, an error happens :
"
In file included from
C:\Users\SingleTact\SingleTactDemo.ino\SingleTactDemo.ino.ino:9:0:
C:\Users\Arduino\libraries\Timer1/Timer1.h:65:6: error: #error ("Unsupported CPU frequency")
#error("Unsupported CPU frequency")
^~~~~
C:\Users\Arduino\libraries\Timer1/Timer1.h:74:6: error: #error ("Unsupported CPU frequency")
#error("Unsupported CPU frequency")
^~~~~
exit status 1
"

I runned the sketch :

void setup() {
   delay( 1000 ) ;
   Serial.begin( 9600 ) ;
   Serial.println( F_CPU ) ;
}

void loop() { }

and got : 48000000
I also tested some basic sketch (like displaying something in the matrix LED) and it works perfectly.

I hope my comment was clear.
Thank you,

Grégoire

You are going to have to find a version or equivalent of the library <Timer1.h> which is compatible with the Uno R4.

The example sketch does not use the timer in a very sophisticated way. It simply uses an interrupt at a specific frequency to increment a variable called "timeStamp_" so you should easily find a suitable substitute. I don't know the R4 so cannot help much more but surely someone else here can.

Incidentally, "timeStamp_" should, in that example, be declared as volatile because it is updated in an interrupt service routine asynchronously with the main code.

use this instead:

volatile unsigned long timeStamp_;

This question may deserve its own topic.

The library Timer1 is not compatible with Uno R4 board