first commit
This commit is contained in:
commit
1f5b8f6c8c
|
|
@ -0,0 +1,68 @@
|
||||||
|
#define SERVER_ADDRESS 0x01
|
||||||
|
#define RH_SPEED 2000
|
||||||
|
#define RH_RX_PIN 11
|
||||||
|
|
||||||
|
#define RH_BUF_LEN 5
|
||||||
|
uint8_t rh_buf[RH_BUF_LEN];
|
||||||
|
|
||||||
|
#define RH_ASK_MAX_MESSAGE_LEN RH_BUF_LEN
|
||||||
|
|
||||||
|
#include <RHDatagram.h>
|
||||||
|
#include <RH_ASK.h>
|
||||||
|
|
||||||
|
RH_ASK driver(RH_SPEED, RH_RX_PIN);
|
||||||
|
|
||||||
|
float t = 0;
|
||||||
|
float h = 0;
|
||||||
|
uint8_t bat_percent = 0;
|
||||||
|
uint8_t bat_raw = 0;
|
||||||
|
|
||||||
|
#define MSG_START 0x00
|
||||||
|
#define MSG_TEMP 0x01
|
||||||
|
#define MSG_HUMID 0x02
|
||||||
|
#define MSG_ERR 0xee
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
if (!driver.init()) {
|
||||||
|
Serial.println("init failed");
|
||||||
|
} else {
|
||||||
|
Serial.println("init done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
uint8_t len = sizeof(rh_buf);
|
||||||
|
if (driver.recv(rh_buf, &len)) {
|
||||||
|
Serial.println("got message: ");
|
||||||
|
switch (rh_buf[0]) {
|
||||||
|
case MSG_START:
|
||||||
|
// start message
|
||||||
|
Serial.println("0x00 start byte");
|
||||||
|
break;
|
||||||
|
case MSG_TEMP:
|
||||||
|
// DHT data
|
||||||
|
Serial.println("0x01 DHT data");
|
||||||
|
memcpy(&t, &rh_buf[1], 4);
|
||||||
|
Serial.print(t);
|
||||||
|
Serial.print("°C - ");
|
||||||
|
break;
|
||||||
|
case MSG_HUMID:
|
||||||
|
// battery data
|
||||||
|
Serial.println("0x02 DHT Humidity");
|
||||||
|
memcpy(&t, &rh_buf[1], 4);
|
||||||
|
Serial.print(t);
|
||||||
|
Serial.print("%");
|
||||||
|
break;
|
||||||
|
case MSG_ERR:
|
||||||
|
// error
|
||||||
|
Serial.println("0xEE error");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// should never happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
/* Fast DHT Lirary
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Sergey Denisov.
|
||||||
|
* Written by Sergey Denisov aka LittleBuster (DenisovS21@gmail.com)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public Licence
|
||||||
|
* as published by the Free Software Foundation; either version 3
|
||||||
|
* of the Licence, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Original library written by Adafruit Industries. MIT license.
|
||||||
|
*
|
||||||
|
* https://github.com/LittleBuster/avr-dht22
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dht22.h"
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define DHT_COUNT 6
|
||||||
|
#define DHT_MAXTIMINGS 85
|
||||||
|
|
||||||
|
|
||||||
|
void dht_init(struct dht22 *dht, uint8_t pin)
|
||||||
|
{
|
||||||
|
dht->pin = pin;
|
||||||
|
/* Setup the pins! */
|
||||||
|
DDR_DHT &= ~(1 << dht->pin);
|
||||||
|
PORT_DHT |= (1 << dht->pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t dht_read(struct dht22 *dht)
|
||||||
|
{
|
||||||
|
uint8_t tmp;
|
||||||
|
uint8_t sum = 0;
|
||||||
|
uint8_t j = 0, i;
|
||||||
|
uint8_t last_state = 1;
|
||||||
|
uint16_t counter = 0;
|
||||||
|
/*
|
||||||
|
* Pull the pin 1 and wait 250 milliseconds
|
||||||
|
*/
|
||||||
|
PORT_DHT |= (1 << dht->pin);
|
||||||
|
_delay_ms(250);
|
||||||
|
|
||||||
|
dht->data[0] = dht->data[1] = dht->data[2] = dht->data[3] = dht->data[4] = 0;
|
||||||
|
|
||||||
|
/* Now pull it low for ~20 milliseconds */
|
||||||
|
DDR_DHT |= (1 << dht->pin);
|
||||||
|
PORT_DHT &= ~(1 << dht->pin);
|
||||||
|
_delay_ms(20);
|
||||||
|
cli();
|
||||||
|
PORT_DHT |= (1 << dht->pin);
|
||||||
|
_delay_us(40);
|
||||||
|
DDR_DHT &= ~(1 << dht->pin);
|
||||||
|
|
||||||
|
/* Read the timings */
|
||||||
|
for (i = 0; i < DHT_MAXTIMINGS; i++) {
|
||||||
|
counter = 0;
|
||||||
|
while (1) {
|
||||||
|
tmp = ((PIN_DHT & (1 << dht->pin)) >> 1);
|
||||||
|
_delay_us(3);
|
||||||
|
|
||||||
|
if (tmp != last_state)
|
||||||
|
break;
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
_delay_us(1);
|
||||||
|
|
||||||
|
if (counter == 255)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_state = ((PIN_DHT & (1 << dht->pin)) >> 1);
|
||||||
|
|
||||||
|
if (counter == 255)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Ignore first 3 transitions */
|
||||||
|
if ((i >= 4) && (i % 2 == 0)) {
|
||||||
|
/* Shove each bit into the storage bytes */
|
||||||
|
dht->data[j/8] <<= 1;
|
||||||
|
if (counter > DHT_COUNT)
|
||||||
|
dht->data[j/8] |= 1;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sei();
|
||||||
|
sum = dht->data[0] + dht->data[1] + dht->data[2] + dht->data[3];
|
||||||
|
|
||||||
|
if ((j >= 40) && (dht->data[4] == (sum & 0xFF)))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dht_read_temp(struct dht22 *dht, float *temp)
|
||||||
|
{
|
||||||
|
if (dht_read(dht)) {
|
||||||
|
*temp = dht->data[2] & 0x7F;
|
||||||
|
*temp *= 256;
|
||||||
|
*temp += dht->data[3];
|
||||||
|
*temp /= 10;
|
||||||
|
|
||||||
|
if (dht->data[2] & 0x80)
|
||||||
|
*temp *= -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dht_read_hum(struct dht22 *dht, float *hum)
|
||||||
|
{
|
||||||
|
if (dht_read(dht)) {
|
||||||
|
*hum = dht->data[0];
|
||||||
|
*hum *= 256;
|
||||||
|
*hum += dht->data[1];
|
||||||
|
*hum /= 10;
|
||||||
|
if (*hum == 0.0f)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dht_read_data(struct dht22 *dht, float *temp, float *hum)
|
||||||
|
{
|
||||||
|
if (dht_read(dht)) {
|
||||||
|
/* Reading temperature */
|
||||||
|
*temp = dht->data[2] & 0x7F;
|
||||||
|
*temp *= 256;
|
||||||
|
*temp += dht->data[3];
|
||||||
|
*temp /= 10;
|
||||||
|
|
||||||
|
if (dht->data[2] & 0x80)
|
||||||
|
*temp *= -1;
|
||||||
|
|
||||||
|
/* Reading humidity */
|
||||||
|
*hum = dht->data[0];
|
||||||
|
*hum *= 256;
|
||||||
|
*hum += dht->data[1];
|
||||||
|
*hum /= 10;
|
||||||
|
if (*hum == 0.0f)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* struct dht22 AVR Lirary
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Sergey Denisov.
|
||||||
|
* Written by Sergey Denisov aka LittleBuster (DenisovS21@gmail.com)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public Licence
|
||||||
|
* as published by the Free Software Foundation; either version 3
|
||||||
|
* of the Licence, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Original library written by Adafruit Industries. MIT license.
|
||||||
|
*
|
||||||
|
* https://github.com/LittleBuster/avr-dht22
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DHT22_H__
|
||||||
|
#define __DHT22_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sensor's port
|
||||||
|
*/
|
||||||
|
#define DDR_DHT DDRB
|
||||||
|
#define PORT_DHT PORTB
|
||||||
|
#define PIN_DHT PINB
|
||||||
|
|
||||||
|
|
||||||
|
struct dht22 {
|
||||||
|
uint8_t data[6]; /* data from sensor store here */
|
||||||
|
uint8_t pin; /* DDR & PORT pin */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init dht sensor
|
||||||
|
* @dht: sensor struct
|
||||||
|
* @pin: PORT & DDR pin
|
||||||
|
*/
|
||||||
|
void dht_init(struct dht22 *dht, uint8_t pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reading temperature from sensor
|
||||||
|
* @dht: sensor struct
|
||||||
|
* @temp: out temperature pointer
|
||||||
|
*
|
||||||
|
* Returns 1 if succeful reading
|
||||||
|
* Returns 0 if fail reading
|
||||||
|
*/
|
||||||
|
uint8_t dht_read_temp(struct dht22 *dht, float *temp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reading humidity from sensor
|
||||||
|
* @dht: sensor struct
|
||||||
|
* @hum: out humidity pointer
|
||||||
|
*
|
||||||
|
* Returns 1 if succeful reading
|
||||||
|
* Returns 0 if fail reading
|
||||||
|
*/
|
||||||
|
uint8_t dht_read_hum(struct dht22 *dht, float *hum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reading temperature and humidity from sensor
|
||||||
|
* @dht: sensor struct
|
||||||
|
* @temp: out temperature pointer
|
||||||
|
* @hum: out humidity pointer
|
||||||
|
*
|
||||||
|
* Returns 1 if succeful reading
|
||||||
|
* Returns 0 if fail reading
|
||||||
|
*
|
||||||
|
* The fastest function for getting temperature + humidity.
|
||||||
|
*/
|
||||||
|
uint8_t dht_read_data(struct dht22 *dht, float *temp, float *hum);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
RadioHead DHT22 Weather Station
|
||||||
|
|
||||||
|
Copyright (c) 2017 Peter Müller <peter@crycode.de> (https://crycode.de)
|
||||||
|
Source: https://git.cryhost.de/crycode/attiny85-radiohead-dht22-weather-sensor/-/tree/master
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**************
|
||||||
|
config
|
||||||
|
**************/
|
||||||
|
|
||||||
|
/// RH_ASK works with ATTiny85, using Arduino 1.0.5 and tinycore from
|
||||||
|
/// https://code.google.com/p/arduino-tiny/downloads/detail?name=arduino-tiny-0100-0018.zip
|
||||||
|
/// Tested with the examples ask_transmitter and ask_receiver on ATTiny85.
|
||||||
|
/// Caution: The RAM memory requirements on an ATTiny85 are *very* tight. Even the bare bones
|
||||||
|
/// ask_transmitter sketch barely fits in eh RAM available on the ATTiny85. Its unlikely to work on
|
||||||
|
/// smaller ATTinys such as the ATTiny45 etc. If you have wierd behaviour, consider
|
||||||
|
/// reducing the size of RH_ASK_MAX_PAYLOAD_LEN to the minimum you can work with.
|
||||||
|
/// Caution: the default internal clock speed on an ATTiny85 is 1MHz. You MUST set the internal clock speed
|
||||||
|
/// to 8MHz. You can do this with Arduino IDE, tineycore and ArduinoISP by setting the board type to "ATtiny85@8MHz',
|
||||||
|
/// setting theProgrammer to 'Arduino as ISP' and selecting Tools->Burn Bootloader. This does not actually burn a
|
||||||
|
/// bootloader into the tiny, it just changes the fuses so the chip runs at 8MHz.
|
||||||
|
/// If you run the chip at 1MHz, you will get RK_ASK speeds 1/8th of the expected.
|
||||||
|
///
|
||||||
|
/// Initialise RH_ASK for ATTiny85 like this:
|
||||||
|
/// // #include <SPI.h> // comment this out, not needed
|
||||||
|
/// RH_ASK driver(2000, 4, 3); // 200bps, TX on D3 (pin 2), RX on D4 (pin 3)
|
||||||
|
/// then:
|
||||||
|
/// Connect D3 (pin 2) as the output to the transmitter
|
||||||
|
/// Connect D4 (pin 3) as the input from the receiver.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// For testing purposes you can connect 2 Arduino RH_ASK instances directly, by
|
||||||
|
/// connecting pin 12 of one to 11 of the other and vice versa, like this for a duplex connection:
|
||||||
|
///
|
||||||
|
/// \code
|
||||||
|
/// Arduino 1 wires Arduino 1
|
||||||
|
/// D11-----------------------------D12
|
||||||
|
/// D12-----------------------------D11
|
||||||
|
/// GND-----------------------------GND
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// You can also connect 2 RH_ASK instances over a suitable analog
|
||||||
|
/// transmitter/receiver, such as the audio channel of an A/V transmitter/receiver. You may need
|
||||||
|
/// buffers at each end of the connection to convert the 0-5V digital output to a suitable analog voltage.
|
||||||
|
///
|
||||||
|
/// Measured power output from RFM85 at 5V was 18dBm.
|
||||||
|
|
||||||
|
// pin with the LED connected
|
||||||
|
#define LED_PIN 4
|
||||||
|
|
||||||
|
// blink time for the LED
|
||||||
|
#define LED_TIME 200
|
||||||
|
|
||||||
|
// pin of the DHT22 sensor
|
||||||
|
#define DHT_PIN 1
|
||||||
|
|
||||||
|
// the own RadioHead address
|
||||||
|
#define RH_OWN_ADDR 0xca // 202
|
||||||
|
|
||||||
|
// the server RadioHead address
|
||||||
|
#define RH_SERVER_ADDR 0x01
|
||||||
|
|
||||||
|
// RadioHead bitrate in bit/s
|
||||||
|
#define RH_SPEED 2000
|
||||||
|
|
||||||
|
// pins for the radio hardware
|
||||||
|
#define RH_RX_PIN 5 // not used, set to a non-existent pin
|
||||||
|
#define RH_TX_PIN 3
|
||||||
|
#define RH_PTT_PIN 5 // not used, set to a non-existent pin
|
||||||
|
|
||||||
|
|
||||||
|
/**************
|
||||||
|
end config
|
||||||
|
**************/
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <avr/sleep.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
// for watchdog wakeup
|
||||||
|
// https://gist.github.com/dwhacks/8055287
|
||||||
|
#ifndef cbi
|
||||||
|
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||||
|
#endif
|
||||||
|
#ifndef sbi
|
||||||
|
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// DHT22 lib
|
||||||
|
// not using the current adafruit dht library, because it eats too many memory
|
||||||
|
#include "dht22.h"
|
||||||
|
dht22 dht;
|
||||||
|
|
||||||
|
#define RH_BUF_LEN 5
|
||||||
|
uint8_t rh_buf[RH_BUF_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
// reduce the RadioHead max message length to save memory
|
||||||
|
#define RH_ASK_MAX_MESSAGE_LEN RH_BUF_LEN
|
||||||
|
|
||||||
|
// RadioHead
|
||||||
|
#include <RH_ASK.h>
|
||||||
|
|
||||||
|
#define MSG_START 0x00
|
||||||
|
#define MSG_TEMP 0x01
|
||||||
|
#define MSG_HUMID 0x02
|
||||||
|
#define MSG_ERR 0xee
|
||||||
|
|
||||||
|
|
||||||
|
RH_ASK rh_driver(RH_SPEED, RH_RX_PIN, RH_TX_PIN, RH_PTT_PIN);
|
||||||
|
|
||||||
|
// watchdog flag
|
||||||
|
volatile boolean f_wdt = 1;
|
||||||
|
|
||||||
|
// temp / humid toggle
|
||||||
|
volatile boolean toggle = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void gotoSleep(void);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// setup the LED pin
|
||||||
|
pinMode(LED_PIN, OUTPUT);
|
||||||
|
|
||||||
|
// init the DHT22
|
||||||
|
dht_init(&dht, DHT_PIN);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t num_blink = 3;
|
||||||
|
|
||||||
|
if (!rh_driver.init()) {
|
||||||
|
num_blink = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// blink 3 times
|
||||||
|
for (uint8_t i = 0; i < num_blink; i++) {
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
_delay_ms(LED_TIME);
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
_delay_ms(LED_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send start message
|
||||||
|
rh_buf[0] = MSG_START;
|
||||||
|
rh_send(1);
|
||||||
|
|
||||||
|
setup_watchdog(6); // approximately 4 seconds sleep
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// main loop
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
if (f_wdt) {
|
||||||
|
f_wdt = 0;
|
||||||
|
// turn on the LED
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
|
||||||
|
// temperature and humidity
|
||||||
|
float t = 0;//float is 32bit = 1byte
|
||||||
|
float h = 0;
|
||||||
|
|
||||||
|
// read from the sensor and check if it was successfull
|
||||||
|
if (dht_read_data(&dht, &t, &h) == 1) {
|
||||||
|
// normal message
|
||||||
|
|
||||||
|
if (toggle) {
|
||||||
|
rh_buf[0] = MSG_TEMP;
|
||||||
|
memcpy(&rh_buf[1], &t, 4);
|
||||||
|
} else {
|
||||||
|
rh_buf[0] = MSG_HUMID;
|
||||||
|
memcpy(&rh_buf[1],&h,4);
|
||||||
|
}
|
||||||
|
toggle = !toggle;
|
||||||
|
|
||||||
|
rh_send(RH_BUF_LEN);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// error message
|
||||||
|
rh_buf[0] = MSG_ERR;
|
||||||
|
rh_send(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn off the LED
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
system_sleep();
|
||||||
|
//_delay_ms(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function to send RadioHead messages from the buffer
|
||||||
|
void rh_send(uint8_t len) {
|
||||||
|
rh_driver.send((uint8_t *)rh_buf, len);
|
||||||
|
rh_driver.waitPacketSent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ISR(WDT_vect)
|
||||||
|
{
|
||||||
|
f_wdt = 1; // set global flag
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set system into the sleep state
|
||||||
|
system wakes up when watchdog is timed out
|
||||||
|
*/
|
||||||
|
void system_sleep() {
|
||||||
|
cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
|
||||||
|
|
||||||
|
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
|
||||||
|
sleep_enable();
|
||||||
|
|
||||||
|
sleep_mode(); // System sleeps here
|
||||||
|
|
||||||
|
sleep_disable(); // System continues execution here when watchdog timed out
|
||||||
|
sbi(ADCSRA, ADEN); // switch Analog to Digitalconverter ON
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
|
||||||
|
6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
|
||||||
|
*/
|
||||||
|
void setup_watchdog(int ii) {
|
||||||
|
|
||||||
|
byte bb;
|
||||||
|
int ww;
|
||||||
|
if (ii > 9 ) ii = 9;
|
||||||
|
bb = ii & 7;
|
||||||
|
if (ii > 7) bb |= (1 << 5);
|
||||||
|
bb |= (1 << WDCE);
|
||||||
|
ww = bb;
|
||||||
|
|
||||||
|
MCUSR &= ~(1 << WDRF);
|
||||||
|
// start timed sequence
|
||||||
|
WDTCR |= (1 << WDCE) | (1 << WDE);
|
||||||
|
// set new watchdog timeout value
|
||||||
|
WDTCR = bb;
|
||||||
|
WDTCR |= _BV(WDIE);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue