Touch radio button

Attiny441/841 + TTP + nRF24l01+

Public Chat
Similar projects worth following
So, let's form our clear TK:

1. The button should look good. At least not bastard.
2. The interior should be in line with the appearance.
3. The number of buttons ... well, from one to four.
4. Touch buttons.
5. Task setting identified only one power source - the battery.
6. The button should be as thin as possible, so we determine the type of battery - lithium.
7. From the battery, we want to live for two years, so turn off all the excess.
8. Interface - wireless using radio waves.
9. Monitor battery status.
10. We agree that our energy budget is limited, so we accept the inconvenience in the form of a late reaction to touch.
13. We will send radiograms only by event - at the moment of touching and at the time of releasing the button. At the moment of holding the finger on the button - we sleep. After - turn off yourself.

Immediately after applying power to the transceiver (not necessarily nRF24 - it can be any other), you must pause to stabilize the oscillator frequency. According to the datasheet, the maximum time it may take is 100 ms. In fact, this pause will be much shorter, but here I take even with a margin. For the formation of such a raza, I use the watchdog timer. The nuance of its use in the old Attns is the following - when the first watchdog is triggered and the interrupt handler is enabled, the MC goes to the handler. If there is no signal for resetting the watchdog timer after that, then the next triggering will reset the MC. Instead of resetting the watchdog, you can also redefine its work period. Also, do not forget about the CCP register (a feature of the late MK with atmega core). I will describe this in the macro section:

#define WDT_int_125mS   CCP = 0xD8; WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP1) | Bit(WDP0)

Next, we need to determine the pin MK, which will supply power through the key to the transceiver and to itself, to the output. Then we configure the SPI section, enable PCINT interrupts, read the parameters from the EEPROM, read the readings from the sensors. Before initializing the transceiver, we need to pause, which we wrote about above. To do this, we just go to sleep. And vachdog wake us up. The section of code that performs the listed actions looks like this

uint8_t address = 1;

        PRR =   (1<<PRTWI) | (1<<PRUSART1) | (1<<PRUSART0) |
            (0<<PRSPI) | (1<<PRTIM2) | (1<<PRTIM1) |

            (1<<PRTIM0) | (1<<PRADC);  


        data[5] = MCUSR;               

        MCUSR = 0;

        DDRB =  (0<<Q1) | (0<<Q3) | (1<<Power);   


        DDRA =  (0<<Q2) | (0<<Q0) | (1<<nRF_CE) | //

            (1<<nRF_CSN) | (1<<SCK_PIN) | (0<<MISO_PIN) |

            (1<<MOSI_PIN) | (0<<nRF_IRQ);      


        GIMSK = (1<<PCIE1) | (1<<PCIE0);       

        PCMSK0 =    (1<<Q0_PCINT) | (1<<Q2_PCINT) | 

        PCMSK1 = (1<<Q1_PCINT) | (1<<Q3_PCINT);     


        data[0] = EEPROM_read(address++);

        data[1] = EEPROM_read(address++);

        data[2] = EEPROM_read(address);



Mandatory action in our program is to measure the voltage level on the battery. To do this, we will measure on the internal ION, and we will use the supply voltage as a reference voltage. But just before the measurement itself, we need to pause for 1 ms to complete the transients. In order not to do this specifically, I turn on the ADC before initializing the transceiver, and I do the measurement after that - the cherished 1 ms just passes. ADC must be turned off - analog circuits consume a small current even in the absence of clocking. we fight for every nanoampere

PRR =   (1<<PRTWI) | (1<<PRUSART1) | (1<<PRUSART0) |
            (0<<PRSPI) | (1<<PRTIM2) | (1<<PRTIM1) |
            (1<<PRTIM0) | (0<<PRADC);


Also, do not forget to turn on the watchdog .... for every fireman ... 
Everything. The preparatory part of the code is over. Next comes the main loop. The main cycle is built on the principle of a finite state machine - in a dream, we are waiting for the input action, we work it out. If there is an exit condition out of the cycle - just de-energize yourself and the transceiver. In the power circuit, we only have the sensor chip.

Package structure: 
0 - address, high byte 
1 - address, low byte 
2 - type 
3 - button status field (Q3 - button 0, Q0 - button 1, Q2 - button 2, Q1 - button 3) 
4 - supply voltage 
5 - add. message (error) 
| __ 
        0 bit PORF bit - power reset load 
        1 bit EXTRF bits - reset reset 
       2 bits bits BORF - reboot by power detector 
       3 bits WDRF bit - reload by watchdog 
       4 bit 
       5 bits 
       6 bits 
       7 bits

   Main loop:

cli (); 

nRF_Transmit_NOACK (data); // Send data without confirmation 

sei (); 

Sleep (SLEEP_MODE_PWR_DOWN); // Go to sleep 

Get_Buttons (); 

if (data [3] == 0) 

nRF_PowerUp_interrupt (); // Enable interrupt...
Read more »

View project log

Enjoy this project?



dAshkova wrote 05/30/2019 at 20:03 point


I deleted the old schema and downloaded the new one. Please take a look. Power is supplied from TTP224: TTP224 output -> turn on the MCU through the protective diode MCU -> turn on the sip key switch (sip...).

  Are you sure? yes | no

Gerben wrote 05/31/2019 at 14:39 point

That makes more sense. Can't find any ratings for the clamping diodes in the datasheet. But the clamping diodes in the AVRs can handle quite a bit of abuse. I know from experience (-;

  Are you sure? yes | no

dAshkova wrote 05/31/2019 at 23:05 point

100 mA :)

  Are you sure? yes | no

Gerben wrote 05/30/2019 at 12:15 point

I'm trying to understand the schematic, but I can't see how the sip32431dr3 is being turned on. The "ON" signal only connects the the IRQ of the NRF24 (as far as I can see).

I was expecting it to be turned on when one of the buttons is touched, and turned off when the NRF24 is done sending the data. But I don't see how.
Might I ask you how this works?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates