Easiest way I can think is to implement the blink without delay method. When millis() - lastTime >= oneSecond, update lastTime and send the value.
It's not that simple here , there are many function calls that run after you call one function to start with that is the transmit_data(); then other stuff runs,
any know how to go about that?
code:
keyFOB code:
/*
2-8-2008
Copyright Spark Fun Electronics© 2008
Nathan Seidle
nathan at sparkfun.com
Key FOB transmitter based on the nRF24L01
2-4uA average current
*/
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
//Define functions
//======================
void ioinit(void); //Initializes IO
void delay_ms(uint16_t x); //General purpose delay
void delay_us(uint8_t x);
uint8_t data_array[4];
#include "nordic-nRF24L01.c"
//======================
ISR(PCINT0_vect)
{
//This vector is only here to wake unit up from sleep mode
}
int main (void)
{
uint16_t button_presses = 0;
ioinit();
transmit_data(); //Send one packet when we turn on
while(1)
{
if( (PINA & 0x8F) != 0x8F )
{
//button_presses++;
data_array[0] = PINA & 0x0F;
data_array[0] |= (PINA & 0x80) >> 3;
data_array[1] = button_presses >> 8;
data_array[2] = button_presses & 0xFF;
data_array[3] = 0;
transmit_data();
}
tx_send_command(0x20, 0x00); //Power down RF
cbi(PORTB, TX_CE); //Go into standby mode
sbi(PORTB, TX_CSN); //Deselect chip
ACSR = (1<<ACD); //Turn off Analog Comparator - this removes about 1uA
PRR = 0x0F; //Reduce all power right before sleep
//asm volatile ("sleep");
//Sleep until a button wakes us up on interrupt
}
return(0);
}
void ioinit (void)
{
//1 = Output, 0 = Input
DDRA = 0xFF & ~(1<<TX_MISO | 1<<BUTTON0 | 1<<BUTTON1 | 1<<BUTTON2 | 1<<BUTTON3 | 1<<BUTTON4);
DDRB = 0b00000110; //(CE on PB1) (CS on PB2)
//Enable pull-up resistors (page 74)
PORTA = 0b10001111; //Pulling up a pin that is grounded will cause 90uA current leak
cbi(PORTB, TX_CE); //Stand by mode
//Init Timer0 for delay_us
TCCR0B = (1<<CS00); //Set Prescaler to No Prescaling (assume we are running at internal 1MHz). CS00=1
/*
DDRA = 0xFF;
DDRB = 0xFF;
while(1)
{
PORTA = 0xFF;
PORTB = 0xFF;
delay_ms(3000);
PORTA = 0x00;
PORTB = 0x00;
delay_ms(3000);
}
*/
configure_transmitter();
GIFR = (1<<PCIF0); //Enable the Pin Change interrupts to monitor button presses
GIMSK = (1<<PCIE0); //Enable Pin Change Interrupt Request
PCMSK0 = (1<<BUTTON0)|(1<<BUTTON1)|(1<<BUTTON2)|(1<<BUTTON3)|(1<<BUTTON4);
MCUCR = (1<<SM1)|(1<<SE); //Setup Power-down mode and enable sleep
sei(); //Enable interrupts
}
//General short delays
void delay_ms(uint16_t x)
{
for (; x > 0 ; x--)
{
delay_us(250);
delay_us(250);
delay_us(250);
delay_us(250);
}
}
//General short delays
void delay_us(uint8_t x)
{
TIFR0 = 0x01; //Clear any interrupt flags on Timer2
TCNT0 = 256 - x; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click
while( (TIFR0 & (1<<TOV0)) == 0);
}
Nrf2401+ module code that is on the keyFOB:
/*
2-8-2008
Copyright Spark Fun Electronics© 2008
Basic routines for nRF24L01
*/
#define TX_PORT PORTA
#define TX_PORT_PIN PINA
#define TX_PORT_DD DDRA
#define TX_SCK 4 //Output
#define TX_MISO 5 //Input
#define TX_MOSI 6 //Output
#define TX_CE 1 //Output
#define TX_CSN 2 //Output
//#define RF_DELAY 5
#define RF_DELAY 55
#define BUTTON0 0
#define BUTTON1 1
#define BUTTON2 2
#define BUTTON3 3
#define BUTTON4 7
//2.4G Configuration - Transmitter
uint8_t configure_transmitter(void);
//Sends command to nRF
uint8_t tx_send_byte(uint8_t cmd);
//Basic SPI to nRF
uint8_t tx_send_command(uint8_t cmd, uint8_t data);
//Sends the 4 bytes of payload
void tx_send_payload(uint8_t cmd);
//This sends out the data stored in the data_array
void transmit_data(void);
//Basic SPI to nRF
uint8_t tx_spi_byte(uint8_t outgoing);
//TX Functions
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//This sends out the data stored in the data_array
//data_array must be setup before calling this function
void transmit_data(void)
{
tx_send_command(0x27, 0x7E); //Clear any interrupts
tx_send_command(0x20, 0x7A); //Power up and be a transmitter
tx_send_byte(0xE1); //Clear TX Fifo
tx_send_payload(0xA0); //Clock in 4 byte payload of data_array
sbi(PORTB, TX_CE); //Pulse CE to start transmission
delay_ms(3);
cbi(PORTB, TX_CE);
}
//2.4G Configuration - Transmitter
//This sets up one RF-24G for shockburst transmission
uint8_t configure_transmitter(void)
{
cbi(PORTB, TX_CE); //Go into standby mode
tx_send_command(0x20, 0x78); //CRC enabled, be a transmitter
tx_send_command(0x21, 0x00); //Disable auto acknowledge on all pipes
tx_send_command(0x24, 0x00); //Disable auto-retransmit
tx_send_command(0x23, 0x03); //Set address width to 5bytes (default, not really needed)
tx_send_command(0x26, 0x07); //Air data rate 1Mbit, 0dBm, Setup LNA
// tx_send_command(0x26, 0x01); //Air data rate 1Mbit, -18dBm, Setup LNA
tx_send_command(0x25, 0x02); //RF Channel 2 (default, not really needed)
data_array[0] = 0xE7;
data_array[1] = 0xE7;
data_array[2] = 0xE7;
data_array[3] = 0xE7;
tx_send_payload(0x30); //Set TX address
tx_send_command(0x20, 0x7A); //Power up, be a transmitter
return(tx_send_byte(0xFF));
}
//Sends the 4 bytes of payload
void tx_send_payload(uint8_t cmd)
{
uint8_t i;
cbi(PORTB, TX_CSN); //Select chip
tx_spi_byte(cmd);
for(i = 0 ; i < 4 ; i++)
tx_spi_byte(data_array[i]);
sbi(PORTB, TX_CSN); //Deselect chip
}
//Sends command to nRF
uint8_t tx_send_command(uint8_t cmd, uint8_t data)
{
uint8_t status;
cbi(PORTB, TX_CSN); //Select chip
tx_spi_byte(cmd);
status = tx_spi_byte(data);
sbi(PORTB, TX_CSN); //Deselect chip
return(status);
}
//Sends one byte to nRF
uint8_t tx_send_byte(uint8_t cmd)
{
uint8_t status;
cbi(PORTB, TX_CSN); //Select chip
status = tx_spi_byte(cmd);
sbi(PORTB, TX_CSN); //Deselect chip
return(status);
}
//Basic SPI to nRF
uint8_t tx_spi_byte(uint8_t outgoing)
{
uint8_t i, incoming;
incoming = 0;
//Send outgoing byte
for(i = 0 ; i < 8 ; i++)
{
if(outgoing & 0b10000000)
sbi(TX_PORT, TX_MOSI);
else
cbi(TX_PORT, TX_MOSI);
sbi(TX_PORT, TX_SCK); //TX_SCK = 1;
delay_us(RF_DELAY);
//MISO bit is valid after clock goes going high
incoming <<= 1;
if( TX_PORT_PIN & (1<<TX_MISO) ) incoming |= 0x01;
cbi(TX_PORT, TX_SCK); //TX_SCK = 0;
delay_us(RF_DELAY);
outgoing <<= 1;
}
return(incoming);
}
Makefile Attached
Makefile (14.5 KB)