Feed on
Posts
Comments

nRF24 Wifi Voltage Sensor

Just a quick simple project I’ve been meaning to do which is to have a nRF24 Wifi module connected to my 12V battery that’s charged by a solar panel and is running the siren of my alarm system. The nRF reader module will connect via USB to the PC and we’ll output the voltage to a file so we can parse the file anyway we like.

IMG_3097 IMG_3099

For the TX side, we use an ATtiny84 and as we’ve seen before, we use an analog voltage reference of 1.1V and I’ll use a 1M / 39K resistor divider which allows us to measure up to 28V (not that I expect it to go that high). We’ll send the voltage once a second.

nvs2

// Read the voltage
sbi(ADCSRA, ADEN); // Turn on ADC
analog_read(adcPin); // First reading is ignored
_delay_ms(1);
int adcValue = analog_read(adcPin); // Read ADC
cbi(ADCSRA, ADEN); // Turn off ADC

// Split up ADC result into 2 bytes
data_out[0] = (adcValue >> 8);
data_out[1] = (adcValue & 0xFF);

// Power up the nRF24L01 and transmit the result
TX_POWERUP;
_delay_ms(3);
mirf_transmit_data();

// Power down the nRF24L01
POWERDOWN;

// Watchdog sleep for 1 second
watchdog_sleep(T1S);

For the RX side, again we use an ATtiny84 and use V-USB to transfer the data received to the PC. If no data is received, we’ll send a “.” dot to let the PC know we’re still communicating to it.

nvs3

USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) {
 ...
    if (data_received == true) {
      // Read data and multiply (1M / 39K resistor divider), you can change depending on your actual resistor values
      double calculateDouble = (double) ((double) ((data_in[0] << 8) | data_in[1]) * 1.074) * 0.026614;
}
...

while (1) {
  if (data_received == false) {
    if (mirf_status() & (1<<RX_DR)) {
      mirf_CE_lo; // Stop listening

      data_in[0] = 0; // Clear the data_in
      data_in[1] = 0;

      mirf_CSN_lo; // Pull down chip select
      spi_transfer(R_RX_PAYLOAD); // Send cmd to read rx payload
      spi_read_data(data_in, mirf_PAYLOAD); // Read payload
      mirf_CSN_hi; // Pull up chip select
      mirf_config_register(STATUS,(1<<RX_DR)); // Reset status register

      data_received = true;
      RX_POWERUP;
      mirf_flush_rx_tx(); // Flush TX/RX
      mirf_CE_hi; // Start listening
    }
  }
  usbPoll();
}

On the PC side, we just the output from V-USB, I did find that you shouldn’t use nBytes to break out of the loop like I used to because after a few hours, the receiver would drop out.

nBytes = 1;
while (1) {
  nBytes = usb_control_msg(handle,
  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
  USB_TRANSFER, 0, 0, (char *)buffer, sizeof(buffer), 5000);

  if (nBytes > 0) {
    if (strcmp(buffer, ".") != 0) {
      printf("%s\n", buffer);
      fwrite(buffer, 1, strlen(buffer), pFile);
      fwrite(newline, 1, strlen(newline), pFile);
      fflush (pFile);
    }
...

It’s all working well after 2 days. Download nRF24_Voltage_Sensor_v0.1

Here’s the graph of our results after 2 days (I used DatPlot to generate this graph) –

nvs1

One Response to “nRF24 Wifi Voltage Sensor”

Leave a Reply