Removing Sleep from code

I do not want to make the system go to sleep because im calling on the other end from the receiver the RPD(equivalent of RSSI) for detecting the power of receiving so please suggest me in the following code what all i need to eliminate:(The code is from the ATTiny24 Nordic FOB)

/*
    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);
}

Too much to look at now but what happens if you take

#include <avr/sleep.h>

out and recompile?

Will clearing the errors until it can compile again work?

Good Idea GoForSmoke but the thing is im thinking to remove this:

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");

it will not turn off anything and i dnt care about the 1 micro ampere that's been expelled atleast not at this time might care in future and till that ASM sleep command i think this much is removing all as i said will not let it go in sleep at all so waking it up from there isn't a question anymore.

What you say?
What is your thinking on my points?

I don't have experience in the sleep functions to say. Only read the notes in the Mega chip doc though I have the Tiny chip doc too.

Even if all you do is comment out the library, you will quickly see all code that uses it. From there, what if any variables are affected might tell more changes to not sleep. Or perhaps you have already found the part to comment out. All I suggest is to make the compiler search for you, it's a trick I know from way back.

Good point! Im doing it all in AVR Studio 5

I do not want to make the system go to sleep ...

Is there some problem with removing this line?

		asm volatile ("sleep");

Build errors are there, i havent touched anything yet but they popped up!!

Error	10	'PORTB' undeclared (first use in this function)	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	63	9	AVRGCC1
Error	4	expected ')' before 'cmd'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	39	30	AVRGCC1
Error	15	expected ')' before 'cmd'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	111	30	AVRGCC1
Error	1	expected '=', ',', ';', 'asm' or '__attribute__' before 'configure_transmitter'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	30	9	AVRGCC1
Error	14	expected '=', ',', ';', 'asm' or '__attribute__' before 'configure_transmitter'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	70	9	AVRGCC1
Error	2	expected '=', ',', ';', 'asm' or '__attribute__' before 'tx_send_byte'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	33	9	AVRGCC1
Error	17	expected '=', ',', ';', 'asm' or '__attribute__' before 'tx_send_byte'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	138	9	AVRGCC1
Error	3	expected '=', ',', ';', 'asm' or '__attribute__' before 'tx_send_command'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	36	9	AVRGCC1
Error	16	expected '=', ',', ';', 'asm' or '__attribute__' before 'tx_send_command'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	125	9	AVRGCC1
Error	5	expected '=', ',', ';', 'asm' or '__attribute__' before 'tx_spi_byte'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	45	9	AVRGCC1
Error	18	expected '=', ',', ';', 'asm' or '__attribute__' before 'tx_spi_byte'	C:\Users\nishant\Documents\AVRStudio 5.1\AVRGCC1\AVRGCC1\nordic-nRF24L01.c	150	9	AVRGCC1

I'm guessing you have the wrong/no chip selected.

I'm guessing you have the wrong/no chip selected.

I have selected the correct chip that is the ATtiny24.

Complete doc on that line of AVR's is here:

All registers and bit references in this section are written in general form. A lower case “x” represents
the numbering letter for the port, and a lower case “n” represents the bit number. However,
when using the register or bit defines in a program, the precise form must be used. For example,
PORTB3 for bit no. 3 in Port B, here documented generally as PORTxn. The physical I/O Registers
and bit locations are listed in “Register Description” on page 67.

Does this even apply I wonder? Down in page 67 at address 0x18 there is PORTB which has only 4 bits.

Did the code you got from SparkFun ever compile and load on the Tiny24 before you changed it?
Was it written for the Tiny24 or will you have to code around hardware exceptions?

Did it make it worked but this time i utilised the winAVR and loaded the HEX by utilising my age old BIT Bang programmer.

NOW, A small thing left to accomplish.

I need to send center button value continuously ONCE every second.

It flashed and runs as expected so far?

Note that I try not to know what your code actually does....

yes it runs

NI$HANT:
Did it make it worked but this time i utilised the winAVR and loaded the HEX by utilising my age old BIT Bang programmer.

NOW, A small thing left to accomplish.

I need to send center button value continuously ONCE every second.

Easiest way I can think is to implement the blink without delay method. When millis() - lastTime >= oneSecond, update lastTime and send the value.

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)

NI$HANT:

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?

Those are libraries or libraries equivalent. I also see delay functions that tell me whoever wrote the code is not so great at real-time or just went simple for the one purpose.

In here below you have the button code that does run fast enough to see button presses.
I don't know what your compiler does for millis() function or if it has one but in Arduino I would;

  1. set up a global unsigned long named lastTime and before that loop below, set it to millis()
    --- #define SECOND 1000
  2. in the button press detect -- if( (PINA & 0x8F) != 0x8F ) { }
    --- if center button is pressed then set lastTime = millis()
  3. after that block and before -- tx_send_command(0x20, 0x00); //Power down RF
    --- make an if block, if (millis() - lastTime >= SECOND) {
    --- lastTime = millis()
    --- set up data_array[ 0 to 3 ] to look just as if the center button was pressed
    --- transmit_data();

What works for the buttons should work to trigger a virtual button press on interval.

Bill Occam gave me a razor once......

	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
	}

OK Mr.GoForSmoke so here goes the code as were mentioning:

unsigned long lastTime = 0;        

#define SECOND 1000        //interval

int main (void)
{
		if( (PINA & 0x8F) != 0x8F )
		{
                         lastTime = millis();
			if (millis() - lastTime >= SECOND) { 
                               lastTime = millis();//am i getting you wrong??here
                               transmit_data();
			       data_array[0] =3 ;

			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
		
}

Not sure if while is needed here?

More like this:

unsigned long lastTime = 0;        

#define SECOND 1000        //interval

int main (void)
{

	while(1)
	{
    
		if( (PINA & 0x8F) != 0x8F ) // this detects actual button presses and transmits
		{
			//button_presses++; // should this line be commented out?
			
			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;

// I don't know how you tell when Center button is pressed, but if it is then maybe set lastTime = millis()
// I don't even know if millis() is the right syntax on your compiler

			transmit_data();
		} // end of button press detection

                // this looks for 1 second to pass, sets up for next second then "presses" the Center button
		if( millis() - lastTime >= SECOND) { 
                               lastTime = millis();

// how should data_array be when Center button is pressed? Code here should make that.

                               transmit_data();
		}
           }

// why bother with the next 5 lines at this point?

                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
		
}

Equivalent of millis() in AVR , i think the much i know there isn't one and thus this needs to be computed.IS there any possibility to get the millis() from the arduino IDE core to the avr?

Is there a timer you can get a milliseconds interrupt from? An unsigned int can count past 1000.

Maybe find and use the millis() code from Arduino which is open?

I am amazed there is no running increment clock in an MCU compiler.