Note: the full software is available on GitHub.
Software Setup
First we create a new Arduino project called rc_boat. We open the Arduino IDE and selectFile ?New
, and call the file rc_boat (or something else if you
prefer).The main function always contains a setup() function for initialisation, and a loop() for the actual control. We now replace the default (barebones) code with the following:
//Global variabeles
unsigned int centis = 0; //centi- seconds
byte seconden = 0; //seconds
byte minuten = 0; //minutes
int alarm = 0;
void setup() {
//Set up Radio Control
RCP_Init();
RCD_Init();
State_Init();
Autonomous_Init();
//Initialise LEDS
TopLed_Init();
LedControl_Init();
LedControl_Disco( HIGH );
TopLed_Out( HIGH );
LedControl_OnBoard( HIGH );
//Let the LEDs blink for a second
delay(1000);
TopLed_Out( LOW );
LedControl_Disco( LOW );
LedControl_OnBoard( LOW );
cli();//deactivate interrupts
tmr0_init();
sei();//Activate interrupts
//Initialise the motor and rudder control
Motor_Init();
Rudder_Init();
}
void loop() {
State_Control();
//LedControl_Disco( HIGH );
delay(100);
}
The code is currently still quite abstract, but the general idea is to:
- Initialise the Radio controller and other stuff
- Initialise the LEDs and let them burn for a second
- Set up the Timer for multi-tasking
- Initialise the motor and rudder controllers
- Run the programme (loop).
//Constants
#define CMR_SECONDE 100 //Count to 10 to time every second
#define CMR_MINUUT 5901 //Count to 609 om time every minute
static byte secondCounter = 0; //Seconds counter
static unsigned int minuteCounter = 0; //16-bits minute counter
//Initialise timer 0;
void tmr0_init(){
TCCR0A = 0; // TCCR0A register = 0
TCCR0B = 0; // TCCR0B as well
TCNT0 = 0; // Reset the counter
OCR0A = 156; // CMR = 156
TCCR0A |= (1 << WGM01); //CTC mode
TCCR0B |= (1 << CS02) | (1 << CS00);//Prescaler = 1024
TIMSK0 |= (1 << OCIE0A); // Activate interrupt Timer 0
}
/**
* Respond to an interrupt of timer 0
*/
ISR(TIMER0_COMPA_vect){//timer0 interrupt
RCP_Update();
RCD_Update();
State_Update();
TopLed_Update();
centis++;
secondCounter++; //count up every interrupt
minuteCounter++; // count up every interrupt
//Monitor_Puls();
if( secondCounter == CMR_SECONDE ){
Autonomous_Update();
secondCounter = 0;
seconden = ( ++seconden ) % 60;
}
if( minuteCounter == CMR_MINUUT ){
minuteCounter = 0;
minuten = ( ++minuten ) % 60;
}
}
The timer is programmed to fire every 10 msec, after which two counters -for seconds and minutes- count up. Some of the control software is updated every 10 milliseconds, like RC, State or TopLed. But the code that controls the Autonomy is updated every second. The
tmr_init
code is called in the setup
of the main programme. This should
be enough to activate the timer. From this point on, all we need to do is to activate the various controllers. For instance, the boat has two LEDs, one of which is mounted under the deck. This LED, called TopLED is activated on pin 5 of Arduino's port D:
#define LED_TOP 5 //Output PortD pin 5
/**
* Initialise the Top LED
*/
void TopLed_Init(){
pinMode( LED_TOP, OUTPUT);//Set the pin for output
}
/**
* Update the top led through the timer interrupt
*/
static boolean led_on = false;
void TopLed_Update(){
byte status = State_GetState();
switch( status ){
case AUTONOMOUS:
if(( counter % AUTO_BLINK ) == 0 )
led_on = !led_on;
break;
case BLOCKED:
if(( counter % BLOCK_BLINK ) == 0)
led_on = !led_on;
break;
default:
led_on = true;
}
TopLed_Out( led_on );
}
byte TopLed_TOP(){
return LED_TOP;
}
void TopLed_Out( boolean signal ){
digitalWrite( LED_TOP, signal );
}
This code has three things that make a recurring pattern for all the controllers:
- The functions all start with the name of the tab (
TopLed_xxx
) - The code contains an
Init
function that is called by thesetup()
of themain
function - The code contains an
Update
function that is called by the timer. In this particular case, the timer is able to blink fast or slow, depending on the state of the boat.
Update
function too deeply, we will
return to this in the next post. Likewise, the other LED, and the LED that is mounted on the Arduino UNO board (pin 13) is controlled by the
following tab: define LED_DISCO 6 //set up disco LED on pint 6
#define LED_ONBOARD 13 //On board LEd is pin 13
void LedControl_Init(){
pinMode( LED_DISCO, OUTPUT );
pinMode( LED_ONBOARD, OUTPUT);
}
byte LedControl_Disco(){
return LED_DISCO;
}
byte LedControl_OnBoard(){
return LED_ONBOARD;
}
void LedControl_Disco( boolean signaal ){
digitalWrite( LED_DISCO, signaal );
}
void LedControl_OnBoard( boolean signaal ){
digitalWrite( LED_ONBOARD, signaal );
}
In this particular case, the LED's do not use the timer, so a
LedControl_Update()
is not necessary.In the next post, we will make the software a bit more complex, by allowing the boat to switch beteen manual and autonomous control.
Geen opmerkingen:
Een reactie posten