Обычно я использую его от трех батареек типа ААА (1,5 В). (Я знаю, оно ниже 5В (4,5В), но вначале работает)
Я уже пробовал запитать его постоянными 5В и произошло то же самое. Я думаю, это связано с программным обеспечением. Но я не вижу в этом никаких проблем. Я не могу заставить Serial.print() работать для дальнейшей отладки.
Вот мой исходный код (на немецком языке):
Код: Выделить всё
#include
#include
#include
#include
#define sensorPin 2
#define TaktLaenge 250 //ms
#define sendeIntervall 15 //min
#define primaerPin 1
#define sekundaerPin 0
//byte saveADCSRA; // variable to save the content of the ADC for later. if needed.
unsigned int counterWD = sendeIntervall * 8; // Count how many times WDog has fired. Used in the timing of the
// loop to increase the delay before the LED is illuminated. For example,
// if WDog is set to 1 second TimeOut, and the counterWD loop to 10, the delay
// between LED illuminations is increased to 1 x 10 = 10 seconds
void sleepNow ()
{
set_sleep_mode ( SLEEP_MODE_PWR_DOWN ); // set sleep mode Power Down
//saveADCSRA = ADCSRA; // save the state of the ADC. We can either restore it or leave it turned off.
ADCSRA = 0; // turn off the ADC
power_all_disable (); // turn power off to ADC, TIMER 1 and 2, Serial Interface
noInterrupts (); // turn off interrupts as a precaution
MCUSR = 0;
WDTCR = bit ( WDCE ) | bit ( WDE ) | bit ( WDIF ); // allow changes, disable reset, clear existing interrupt
WDTCR = bit ( WDIE ) | bit ( WDP3 )| bit ( WDP0 ); // set WDIE ( Interrupt only, no Reset ) and 8 second TimeOut. Table for WDPs: http://shelvin.de/wp-content/uploads/2014/09/atmega328-wdt-pre-500.jpg
wdt_reset (); // reset WDog to parameters
sleep_enable (); // allows the system to be commanded to sleep
interrupts (); // turn on interrupts
sleep_cpu (); // send the system to sleep, night night!
sleep_disable (); // after ISR fires, return to here and disable sleep
power_all_enable (); // turn on power to ADC, TIMER1 and 2, Serial Interface
// ADCSRA = saveADCSRA; // turn on and restore the ADC if needed. Commented out, not needed.
}
void sleep1sec ()
{
set_sleep_mode ( SLEEP_MODE_PWR_DOWN ); // set sleep mode Power Down
//saveADCSRA = ADCSRA; // save the state of the ADC. We can either restore it or leave it turned off.
ADCSRA = 0; // turn off the ADC
power_all_disable (); // turn power off to ADC, TIMER 1 and 2, Serial Interface
noInterrupts (); // turn off interrupts as a precaution
MCUSR = 0;
WDTCR = bit ( WDCE ) | bit ( WDE ) | bit ( WDIF ); // allow changes, disable reset, clear existing interrupt
WDTCR = bit ( WDIE ) | bit ( WDP2 )| bit ( WDP1 ); // set WDIE ( Interrupt only, no Reset ) and 1 second TimeOut. Table for WDPs: http://shelvin.de/wp-content/uploads/2014/09/atmega328-wdt-pre-500.jpg
wdt_reset (); // reset WDog to parameters
sleep_enable (); // allows the system to be commanded to sleep
interrupts (); // turn on interrupts
sleep_cpu (); // send the system to sleep, night night!
sleep_disable (); // after ISR fires, return to here and disable sleep
power_all_enable (); // turn on power to ADC, TIMER1 and 2, Serial Interface
// ADCSRA = saveADCSRA; // turn on and restore the ADC if needed. Commented out, not needed.
}
void sleep250ms ()
{
set_sleep_mode ( SLEEP_MODE_PWR_DOWN ); // set sleep mode Power Down
//saveADCSRA = ADCSRA; // save the state of the ADC. We can either restore it or leave it turned off.
ADCSRA = 0; // turn off the ADC
power_all_disable (); // turn power off to ADC, TIMER 1 and 2, Serial Interface
noInterrupts (); // turn off interrupts as a precaution
MCUSR = 0;
WDTCR = bit ( WDCE ) | bit ( WDE ) | bit ( WDIF ); // allow changes, disable reset, clear existing interrupt
WDTCR = bit ( WDIE ) | bit ( WDP2 ); // set WDIE ( Interrupt only, no Reset ) and 0.5 second TimeOut. Table for WDPs: http://shelvin.de/wp-content/uploads/2014/09/atmega328-wdt-pre-500.jpg
wdt_reset (); // reset WDog to parameters
sleep_enable (); // allows the system to be commanded to sleep
interrupts (); // turn on interrupts
sleep_cpu (); // send the system to sleep, night night!
sleep_disable (); // after ISR fires, return to here and disable sleep
power_all_enable (); // turn on power to ADC, TIMER1 and 2, Serial Interface
// ADCSRA = saveADCSRA; // turn on and restore the ADC if needed. Commented out, not needed.
}
ISR ( WDT_vect )
{
wdt_disable (); // until next time....
//counterWD ++; // increase the WDog firing counter. Used in the loop to time the flash
// interval of the LED. If you only want the WDog to fire within the normal
// presets, say 2 seconds, then comment out this command and also the associated
// commands in the if ( counterWD..... ) loop, except the 2 digitalWrites and the
// delay () commands.
} // end of ISR
namespace RCautoSender {
uint8_t ohneUEbertragAddieren(uint8_t daten[15], uint8_t anzahl){
uint8_t output = 0;
for(uint8_t i = 0; i < anzahl; i++){
output ^= daten[i];
}
return output;
}
void sendeFloat(float Zahl){
int VorKomma;
int NachKomma;
if(Zahl < 0){
VorKomma = Zahl * -1; // Wird automatisch abgerundet
NachKomma = (Zahl + VorKomma) * -10; // -10 aendern, fuer mehr Kommastellen
} else {
VorKomma = Zahl; // Wird automatisch abgerundet
NachKomma = (Zahl - VorKomma) * 10; // 10 aendern, fuer mehr Kommastellen
}
uint32_t bits = 0;
uint8_t einsen[13];
uint8_t gemeinsamesI = 0;
uint8_t einsenZaehler = 0;
for(uint8_t i = 0; i < 8; gemeinsamesI++){
if(((gemeinsamesI + 1) & gemeinsamesI) != 0){ // gemeinsamesI+1 (bei 1 angefangen) ist keine Zweierpotenz und somit kein Pharitaetsbit
bitWrite(bits, gemeinsamesI, bitRead(VorKomma, i));
if(bitRead(bits, gemeinsamesI) == 1){
einsen[einsenZaehler] = gemeinsamesI + 1;
einsenZaehler++;
}
i++;
}
}
for(uint8_t i = 0; i < 5; gemeinsamesI++){
if(((gemeinsamesI + 1) & gemeinsamesI) != 0){ // gemeinsamesI+1 (bei 1 angefangen) ist keine Zweierpotenz und somit kein Pharitaetsbit
if(i == 4){ // Positiv oder Negativ Indikator: 0=Positiv; 1=Negativ
bitWrite(bits, gemeinsamesI, Zahl < 0);
if(Zahl < 0){
einsen[einsenZaehler] = gemeinsamesI + 1;
einsenZaehler++;
}
i++;
} else {
bitWrite(bits, gemeinsamesI, bitRead(NachKomma, i));
if(bitRead(bits, gemeinsamesI) == 1){
einsen[einsenZaehler] = gemeinsamesI + 1;
einsenZaehler++;
}
i++;
}
}
}
uint8_t pharitaeten = ohneUEbertragAddieren(einsen, einsenZaehler);
uint8_t pharitaetszaehler = 0;
for(uint8_t i = 0; i < gemeinsamesI; i++){
if(((i + 1) & i) == 0){ // i+1 (bei 1 angefangen) ist eine Zweierpotenz und somit ein Pharitaetsbit
bitWrite(bits, i, bitRead(pharitaeten, pharitaetszaehler));
if(bitRead(pharitaeten, pharitaetszaehler) == 1){
einsenZaehler++;
}
pharitaetszaehler++;
}
}
pinMode(primaerPin, OUTPUT);
pinMode(sekundaerPin, OUTPUT);
//bits = 0b0011001110000110000;
byte startbits = 0b01; // wird wie binaer 10 behandelt
digitalWrite(sekundaerPin, HIGH);
sleep1sec(); //delay(1000);
for(int i = 0; i < 2; i++){ // Um ca. die gleiche zusaetzliche Zeit wie in der realen Schleife zu benötigen
digitalWrite(primaerPin, bitRead(startbits, i));
sleep250ms(); //delay(TaktLaenge);
}
for(int i = 0; i < 10; i++){
digitalWrite(primaerPin, bitRead(bits, i));
sleep250ms(); //delay(TaktLaenge);
}
digitalWrite(primaerPin, LOW);
sleep250ms(); //delay(1000);
for(int i = 0; i < 2; i++){ // Um ca. die gleiche zusaetzliche Zeit wie in der realen Schleife zu benötigen
digitalWrite(primaerPin, bitRead(startbits, i));
sleep250ms(); //delay(TaktLaenge);
}
for(int i = 10; i < gemeinsamesI; i++){
digitalWrite(primaerPin, bitRead(bits, i));
sleep250ms(); //delay(TaktLaenge);
}
//Ist die Anzahl aller Bits ungerade (ungerade = 1)
digitalWrite(primaerPin, einsenZaehler % 2);
sleep250ms(); //delay(TaktLaenge);
digitalWrite(sekundaerPin, LOW);
digitalWrite(primaerPin, LOW);
pinMode(primaerPin, INPUT);
pinMode(sekundaerPin, INPUT);
}
void sendeFehler(){ // Sendet eine -0.00 (waehre eigentlich 0.00) der Empfänger erkennt das.
pinMode(primaerPin, OUTPUT);
pinMode(sekundaerPin, OUTPUT);
digitalWrite(sekundaerPin, HIGH);
sleep1sec(); //delay(1000);
digitalWrite(primaerPin, HIGH);
sleep250ms(); //delay(TaktLaenge);
digitalWrite(primaerPin, LOW);
sleep250ms(); //delay(TaktLaenge);
// Die mit Hammingcode gesicherte version von -0,0 ist 010000000000000101b (mit 2. Erkennung: 0100000000 010 00000101)
// (primaerPin ist bereits auf 0)
sleep250ms();
digitalWrite(primaerPin, 1);
sleep250ms();
digitalWrite(primaerPin, 0);
sleep1sec();
sleep1sec();
sleep250ms();
digitalWrite(primaerPin, 1);
sleep250ms();
digitalWrite(primaerPin, 0);
sleep250ms();
sleep1sec();
sleep250ms();
digitalWrite(primaerPin, 1);
sleep250ms();
digitalWrite(primaerPin, 0);
sleep250ms();
digitalWrite(primaerPin, 1);
sleep250ms();
//die Anzahl aller Bits ist ungerade (ungerade = 1)
// (primaerPin ist bereits auf 1)
sleep250ms();
digitalWrite(sekundaerPin, LOW);
digitalWrite(primaerPin, LOW);
pinMode(primaerPin, INPUT);
pinMode(sekundaerPin, INPUT);
}
};
OneWire ds(sensorPin);
float tempC; // temperature in Celsius
void setup() {
}
void loop() {
if ( counterWD >= sendeIntervall * 7.5 ){
byte i;
byte present = 0;
byte type_s;
byte data[9];
byte addr[8];
if ( !ds.search(addr)) {
ds.reset_search();
sleep1sec();
if ( !ds.search(addr)) {
RCautoSender::sendeFehler(); // No more addresses.
ds.reset_search();
counterWD = 0;
sleepNow();
return;
}
}
if (OneWire::crc8(addr, 7) != addr[7]) {
RCautoSender::sendeFehler(); // CRC is not valid!
counterWD = 0;
sleepNow();
return;
}
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
//Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
//Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
//Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
RCautoSender::sendeFehler(); //Serial.println("Device is not a DS18x20 family device.");
counterWD = 0;
sleepNow();
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
//delay(1000); // maybe 750ms is enough, maybe not
sleep1sec();
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1]
Подробнее здесь: [url]https://stackoverflow.com/questions/78172980/digispark-attiny85-suddenly-stopps-sending-data[/url]