I have tried to compile in the IDE and using CodeBlocks and both give the same results:
multiple errors with: "undefined Reference to 'Timer1'" I have made sure that i can open the Timer1.h and Timer1.cpp files right from codeblocks when it loads, but i still get the errors. even in the IDE.
Not sure how to attach my code for review, it adds all sorts of text within my code.
RC_Channel_Mod.cpp.o: In function `FINISHED_ISR()':
C:\Users\Angela\AppData\Local\Temp\build423434619881223618.tmp/RC_Channel_Mod.cpp:131: undefined reference to `Timer1'
C:\Users\Angela\AppData\Local\Temp\build423434619881223618.tmp/RC_Channel_Mod.cpp:131: undefined reference to `Timer1'
RC_Channel_Mod.cpp.o: In function `FALLING_ISR()':
C:\Users\Angela\AppData\Local\Temp\build423434619881223618.tmp/RC_Channel_Mod.cpp:124: undefined reference to `Timer1'
C:\Users\Angela\AppData\Local\Temp\build423434619881223618.tmp/RC_Channel_Mod.cpp:124: undefined reference to `Timer1'
RC_Channel_Mod.cpp.o: In function `Transition()':
C:\Users\Angela\AppData\Local\Temp\build423434619881223618.tmp/RC_Channel_Mod.cpp:251: undefined reference to `Timer1'
RC_Channel_Mod.cpp.o:C:\Users\Angela\AppData\Local\Temp\build423434619881223618.tmp/RC_Channel_Mod.cpp:251: more undefined references to `Timer1' follow
I am using the TimerOne library and its in the include file on top. The whole program didn't fit. I didn't think you need to initialize classes defined in a xxx.h file if they are defined there.
#include <Arduino.h>
#include <..\libraries\PinChangeInt\PinChangeInt.h>
#include <..\libraries\TimerOne\TimerOne.h>
// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
#define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PIN_STATE // to indicate that you don't need the pinState
#define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin
// define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation.
#define DISABLE_PCINT_MULTI_SERVICE
/*
Copyright 2011 Lex Talionis (Lex.V.Talionis at gmail)
This program is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any
later version.
This code uses pin change interrupts and timer 1 to mesure the
time between the rise and fall of 3 channels of PPM
(Though often called PWM, see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253149521/all)
on a typical RC car reciver. It could be extended to as
many channels as you like. It uses the PinChangeInt library
to notice when the signal pin goes high and low, and the
Timer1 library to record the time between.
*/
#define PIN_IN_COUNT 3 //number of channels attached to the reciver
#define MAX_CHANGE_PINS PIN_IN_COUNT
#define PIN_OUT_COUNT 4
#define MAX_PINS 7
#define MaxPulseWait 22000
#define RC_Lights_Pin 13
#define CH5Rec 0
#define CH6Rec 1
#define CH7Rec 2 //Main loop state assignments
#define CH8Send 3
#define CH9Send 4
#define CH10Send 5
#define DETECTState 0 // RC_DETECTState (D_State) Assignments
#define READINGState 1
#define DETECTEDState 2
#define CONFIGOUTState 0 // RC_CONTROLSENDState (O_State) Assignments
#define FINISHEDState 1
struct RC_Channel
{
byte Pin;
int RecVal;
int SendVal;
byte IncVal;
int MinVal;
int MaxVal;
boolean UpdatedFlag;
boolean SentFlag;
};
RC_Channel RC_Ch[6];
byte Offset_Value = 0;
byte State = 0;//CH1Rec
byte D_State = DETECTState;
byte O_State = CONFIGOUTState;
byte PW_Out = 0;
byte BeaconBrightness = 0;
byte BeaconLoop =0;
byte Beacon_Period = 60; //maximum number of Pulse loop cycles in one Beacon Period (60 decimal)
float Pi = 3.1415926535897932384; //Constant Pi used to convert to radians
boolean Beacon_ON = false;
float SinValue = 0; //Sinewave value for sinstep degrees
void setup()
{
//longest pulse rep period in PPM is usally 20 milliseconds,
// initialize timer1, and set a 22ms second period(22000us)
Timer1.initialize(MaxPulseWait);
// Configure Timer2 for Fast PWM with max 256 count continuously running
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS22) | _BV(CS21) |_BV(CS20);// prescaler to 1024 change freq of 61Hz
//OCR2A = 0; //Pin D3 if you include _BV(COM2AB1) in TCCR2A otherwise set up for normal pin use
OCR2B = 0; //Pin D11
// end timer2 configure
// Set initial values for all of RC_Ch[], Pin will be assigned in for loop below
RC_Ch[0].Pin = 4;
RC_Ch[0].RecVal = RC_Ch[0].SendVal = 1500;
RC_Ch[0].IncVal = 2;
RC_Ch[0].MinVal = 1000;
RC_Ch[0].MaxVal = 2000;
RC_Ch[0].SentFlag = RC_Ch[0].UpdatedFlag = false;
RC_Ch[1] = RC_Ch[0];
RC_Ch[2] = RC_Ch[0];
RC_Ch[3] = RC_Ch[0];
RC_Ch[4] = RC_Ch[0];
RC_Ch[5] = RC_Ch[0];
for(byte i = 0; i < PIN_IN_COUNT; i++ ) // set receive pins to RC_Ch[]
{
//RC_Receive Pins Ch1:4, Ch2:5, Ch3:6
RC_Ch[i].Pin = (i+4);
pinMode( RC_Ch[i].Pin, INPUT); //set the pin to input
digitalWrite(RC_Ch[i].Pin, HIGH); //use the internal pullup resistor
};
for(byte i = PIN_IN_COUNT; i < (MAX_PINS-1); i++) //set send pins tp RC_Ch[]
{
//RCSend Pins Ch4:9, Ch5:10, Ch6:11 note that CH6 corresponds to Pin 11 and is the PWM ch
RC_Ch[i].Pin = (i+6);
pinMode(RC_Ch[i].Pin, OUTPUT); //set the pin to input
digitalWrite(RC_Ch[i].Pin, LOW); //
};
//Configure the extra running lights pin (13)
pinMode(RC_Lights_Pin,OUTPUT);
digitalWrite(RC_Lights_Pin,LOW);
} // End setup()
void RISING_ISR()
{
Timer1.start();
} //End RISING_ISR()
void FALLING_ISR()
{
Timer1.stop(); //Stop Timer1
RC_Ch[State].RecVal = TCNT1;
++D_State;
} // End FALLING_ISR()
void FINISHED_ISR()
{
Timer1.stop(); //stop Timer1
++O_State;
} //FINISHED_ISR()
void RC_DETECT()
{
switch (D_State)
{
case DETECTState: //Configure to capture a pulse width
attachInterrupt(RC_Ch[State].Pin, RISING_ISR, RISING);
Timer1.initialize(2200);
delay(20); //Wait for interrupt 20ms
break;
case READINGState: //We have detected a pulse and are reading the PulseWidth.
detachInterrupt(RC_Ch[State].Pin); //detach falling edge
attachInterrupt(RC_Ch[State].Pin, FALLING_ISR, FALLING); //attach the falling edge
delay(4); //Wait for interrupt 4ms
break;
case DETECTEDState: //We have captured the PulseWidth and have a value to transmit
detachInterrupt(RC_Ch[State].Pin); //detatch interrupts
RC_Ch[State].UpdatedFlag = true;
RC_Ch[State].SentFlag = false;
break;
} //End Switch D_State
}//End RC_DETECT()
void RC_CONTROLSEND()
{
switch (O_State)
{
case CONFIGOUTState: //Configure to Transmit a pulse width
Timer1.attachInterrupt(FINISHED_ISR,RC_Ch[State].SendVal); // Define EndCount Interrupt
RC_Ch[State].Pin = HIGH;
delay(3); //wait for interrupt and timeout in 3ms to send pulse
break;
case FINISHEDState: //We have sent the Pulse and need to reconfigure
//need to verify settings
Timer1.detachInterrupt();
Timer1.stop(); //Stop Timer1
RC_Ch[State].Pin = LOW;
RC_Ch[State].SentFlag = true;
RC_Ch[State].UpdatedFlag = false;
break;
}//End Switch (O_State)
}// End RC_CONTROLSEND()
void Limit_Range()
{
if(RC_Ch[State].SendVal > RC_Ch[State].MaxVal) RC_Ch[State].SendVal = RC_Ch[State].MaxVal; // Increase value if control is higher than flap value
else if(RC_Ch[State].SendVal < RC_Ch[State].MinVal) RC_Ch[State].SendVal = RC_Ch[State].MinVal; // Decrease value if control is less than flap value
}//End Limit_Range()
void Increment()
{
RC_Ch[State].SendVal = RC_Ch[State].SendVal + RC_Ch[State].IncVal;
Limit_Range();
} //End Increment()
void Decrement()
{
RC_Ch[State].SendVal = RC_Ch[State].SendVal - RC_Ch[State].IncVal;
Limit_Range();
return;
} //End Decrement()
void GET_OFFSET()
{
//First determine the offset between the control servo and the Slowed control value in ms
if(RC_Ch[State].UpdatedFlag == true)
{
Offset_Value = RC_Ch[State].SendVal - RC_Ch[State].RecVal;
if(Offset_Value > 2) Increment(); // Increase value if control is higher than flap value
else if(Offset_Value < 2) Decrement(); // Decrease value if control is less than flap value
RC_Ch[State].UpdatedFlag = false;
}//End If
} //End GET_OFFSET()
void BeaconON()
{
RC_Ch[State].RecVal = 2000;
digitalWrite(RC_Lights_Pin,HIGH);
Beacon_ON = true;
} //End BeaconON()
void BeaconOFF()
{
RC_Ch[State].RecVal = 1000;
digitalWrite(RC_Lights_Pin,LOW);
Beacon_ON =false;
} //End BeaconOFF()
void Calc_Beacon_Brightness() // setup Beacon blink brightness value: NOT UPDATESD
{
// determine sinewave value for sinstep angle
SinValue = sin((BeaconLoop*2*Pi)/Beacon_Period); //convert sinestep to radians, then divides by number of steps about one Sec
//determines LED brightness value for the PWM
BeaconBrightness = 127 + byte(128 * SinValue) ; //offset value to midpoint and scale sinewave from 0 to 255 range
//Limit_Range();
PW_Out = byte(BeaconBrightness);
++BeaconLoop % Beacon_Period; // Modulo Beacon_Period
} // End Calc_Beacon_Brightness()
void Calc_Beacon()
{
if(RC_Ch[State].UpdatedFlag == true)
{
if(RC_Ch[State].RecVal >= 1500) BeaconON();// Check for Beacon ON status
else BeaconOFF();
RC_Ch[State].UpdatedFlag = false;
}//end if RC_Ch[State}.Updated == true
if(Beacon_ON == true) Calc_Beacon_Brightness();// Check for Beacon ON status
else PW_Out = 0x00;
OCR2B = PW_Out;
D_State = DETECTState;
} //End Calc_Beacon()
void Transition() //Entered TransitionState: Change Mode from Capture to Output
{
Timer1.stop(); //Stop Timer1
//Configure Timer1 for Pulse period send
Timer1.setPeriod(2200);
Timer1.stop(); //Stop Timer1
O_State = CONFIGOUTState;
} //End Transition()
Yes, I believe you do, though it's not because it's a library, just it's functionality.
From the /playground/code/timer1 documentation;
initialize(period)
You must call this method first to use any of the other methods.
You can optionally specify the timer's period here (in microseconds), by default it is set at 1 second.
Note that this breaks analogWrite() for digital pins 9 and 10 on Arduino.
Ah, I see you do have timer1.initialise in your setup section;
void setup()
{
//longest pulse rep period in PPM is usally 20 milliseconds,
// initialize timer1, and set a 22ms second period(22000us)
Timer1.initialize(MaxPulseWait);
Well just for grins i tried it again, and it didnt help , same errors. By the way I do initialize it in setup() but i tried doing it just after the variable initializations. by the way here is the rest of my code (just over the limit)
void loop()
{
switch (State) {
case CH5Rec: //Entered CH5Rec: read command and capture "Gear"
RC_DETECT();
GET_OFFSET();
++State;
break;
case CH6Rec: //Entered CH6Rec: read command and capture "Flaps"
RC_DETECT();
GET_OFFSET();
++State;
break;
case CH7Rec: //Entered CH7Rec
RC_DETECT();
GET_OFFSET();
Transition();
++State;
break;
case CH8Send: //Entered CH8Send: Send "Gear" Command
RC_CONTROLSEND();
++State;
break;
case CH9Send: //Entered CH9Send: Send "Flaps" Command
RC_CONTROLSEND();
++State;
break;
case CH10Send: //Entered CH10Send: Send "Flaps" Command
Calc_Beacon();
State=0;
break;
}//end Switch (mainState)
} //end loop()
JA_Navarro:
I am using the TimerOne library and its in the include file on top. The whole program didn't fit. I didn't think you need to initialize classes defined in a xxx.h file if they are defined there.
Have you posted the code that declares Timer1? I haven't spotted it yet.
If your sketch doesn't compile then I think any worries about whether you're correctly initialising it are a red herring; missing initialisation might stop it working but would not stop it compiling.
From reading the error, it seems every reference you make to Timer1 is undefined.
I am wondering if you have verified the location of your TimeOne library?
Also, just a small thought is going through my mind say that Arduino libraries are included with a slight syntax difference to external libraries;
I use quotes to include files, not generally between <> brackets.
Can someone confirm this?
Is your library imported into the Arduino library or have you kept it external?
Are you using 1.0,1? That version thinks that it is perfectly OK if an include file can't be found. Try compiling on 1.0, instead. If you then get a message telling you that TimerOne.h can't be found, you haven't installed the library in the correct place. I do wish the Arduino team would fix the damned problem and get 1.0.2 out.
OK when using CodeBlocks, I copied the PinChangeInt and TimerOne folders under my main program directory libraries folder, then I used the following lines and it finally compiled in CodeBlocks too.
Thanks Everyone for all your help!