The main program talks to the ANT+ device, decides on a message and drives our display.
The code is found at RetroRunnerReadout.ino.
The program follows the standard Arduino/MCU setup then loop paradigm.
It sets up the hardware (display and ANT+) and following that displays a few setup messages on the LED 7-segment display.
The code is found at RetroRunnerReadout.ino.
The program follows the standard Arduino/MCU setup then loop paradigm.
It sets up the hardware (display and ANT+) and following that displays a few setup messages on the LED 7-segment display.
setup()
Setup enables the hardware for the ANT+ and MAX7219 chips and prints a few messages to the display.{
Serial.begin(CONSOLE_BAUD_RATE);
SERIAL_INFO_PRINTLN("CanToo Runner!");
mydisplay.shutdown(0, false); // turns on display
mydisplay.setIntensity(0, DISPLAY_INTENSITY); // 0..15 = brightest
mydisplay.clearDisplay(0);
mydisplay.shutdown(0, true); // turns off display
//Print a few startup messages
for(unsigned int counter_setup = 0; counter_setup < STARTUP_TEXTS_COUNT; counter_setup++)
{
const char * const* str_in_pm = &startup_texts[ counter_setup ];
char text[MAX_CHARS_TO_DISPLAY_STR];
CLEAR_STR(text, MAX_CHARS_TO_DISPLAY_STR);
//Read from PROG_MEM
strncpy_P(text, (char*)pgm_read_word( str_in_pm ), MAX_CHARS_TO_DISPLAY_STR);
print_and_delay( text );
}
SERIAL_DEBUG_PRINTLN_F("ANT+ Config...");
//We setup an interrupt to detect when the RTS is received from the ANT chip.
//This is a 50 usec HIGH signal at the end of each valid ANT message received from the host at the chip
attachInterrupt(0/*0==pin2==RTS_PIN*/, isr_ant, RISING);
ant_serial.begin( ANTPLUS_BAUD_RATE );
antplus.begin( ant_serial );
//This should not be strictly necessary - the device should always come up by itself....
//But let's make sure we didn't miss the first RTS in a power-up race
antplus.hardwareReset();
SERIAL_DEBUG_PRINTLN_F("ANT+ Config Finished");
}
Following that it drops into the processing loop. The loop alternates between servicing sending/receiving ANT+ messages and displaying messages to the screen.
loop()
The loop function repeats executing ANT+ code and displaying (). The ANT+ code is given priority at the start as it establishes an ANT+ channel.
{
loop_antplus();
//Get the ANT+ channels up quickly
// then send some display messages
if(ret_val_ce == ANT_CHANNEL_ESTABLISH_COMPLETE)
{
//This has blocking sleeps in it and so causes things to stop
loop_display();
}
}
loop_display()
The display messages are hard coded loops. The loops however have special keywords that are replaced dynamically updating distance travelled, heart rate, a random name or motivation quote etc.{
static int counter = 0;
char text[MAX_CHARS_TO_DISPLAY_STR];
//Pull a string from the loop texts
//These are one per loop and some of them get replaced if they are "magic" texts
const char * const* str_in_pm = &loop_texts[ counter % LOOP_TEXTS_COUNT ];
CLEAR_STR(text, MAX_CHARS_TO_DISPLAY_STR);
strncpy_P(text, (char*)pgm_read_word( str_in_pm ), MAX_CHARS_TO_DISPLAY_STR);
//Replace, print and then delay.
print_and_delay( text );
counter++;
}
loop_antplus()
The ANT+ loop does two things. Firstly it sets up an ANT+ channel for receiving SDM/Footpod broadcasts and then it processes any messages coming in on that channel (updating variables that are read in the string replace function).
{
byte packet_buffer[MAXPACKETLEN];
ANT_Packet * packet = (ANT_Packet *) packet_buffer;
MESSAGE_READ ret_val = MESSAGE_READ_NONE;
//We received an interrupt on the nRF24AP2 RTS pin
if(state == 1)
{
antplus.rTSHighAssertion();
//Clear the ISR flag
state = 0;
}
ret_val = antplus.readPacket(packet, MAXPACKETLEN, 0 );
if((ret_val == MESSAGE_READ_EXPECTED) || (ret_val == MESSAGE_READ_OTHER))
{
//Some broadcast packets will update globals (like HRM and Footpod)
process_packet(packet);
}
//Only one channel gets setup in this version
if(ret_val_ce != ANT_CHANNEL_ESTABLISH_COMPLETE)
{
//This function will progress a state machine in
//the ANT+ library to establish a channel
ret_val_ce = antplus.progress_setup_channel( &sdm_channel );
if(ret_val_ce == ANT_CHANNEL_ESTABLISH_COMPLETE)
{
SERIAL_DEBUG_PRINTLN_F( "Channel established!" );
}
}
}
If you want to dig deeper, see the interrupt, string replacement code look at the code on github. RetroRunnerReadout.ino.The libraries created for the project are at MAX72xx_SPI_Arduino and ANTPlus_Arduino.
If you want to dig deeper, see the interrupt, string replacement code look at the code on github. RetroRunnerReadout.ino.The libraries created for the project are at MAX72xx_SPI_Arduino and ANTPlus_Arduino.
No comments:
Post a Comment