Digispark ATtiny85 внезапно перестает отправлять данныеC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Digispark ATtiny85 внезапно перестает отправлять данные

Сообщение Anonymous »

Делаю радиодатчик температуры. Он работает отлично, пока внезапно не перестает отправлять данные. Я использую Arduino IDE с Digispark (ATtiny85), и это обычный загрузчик Arduino. Чтобы снизить энергопотребление, я использую сторожевой таймер для включения и выключения процессора. Иногда работает долго (до 3 дней), а иногда всего несколько часов. Если я затем перезагрузлю его через контакт 5, он снова заработает.
Обычно я использую его от трех батареек типа ААА (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]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • PINB ATtiny85 случайно мигает
    Anonymous » » в форуме C++
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous
  • Attiny85 Software Latch с Buttonhold для запуска / сон.
    Anonymous » » в форуме C++
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • Attiny85 программное обеспечение с помощью кнопки удержание для запуска / смены спящего состояния
    Anonymous » » в форуме C++
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • Unity Socket io перестает отправлять данные на несколько секунд после нормальной работы в течение 45-50 секунд.
    Anonymous » » в форуме C#
    0 Ответы
    123 Просмотры
    Последнее сообщение Anonymous
  • Приложение PHP-FPM внезапно перестает отвечать на запросы до перезапуска контейнера
    Anonymous » » в форуме Php
    0 Ответы
    29 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»