Sari la conținut
ELFORUM - Forumul electronistilor

Attiny85 freeze


Postări Recomandate

Am intr-o aplicatie, un Attiny85 printr-un NPN un releu (+flyback). Pentru alimentare, dintr-o sursa in comutatie de 12V alimentare pentru releu, si pentru 5V o alta sursa in comutatie reglata pe 5.01V. uC are in apropiere de alimentare 100nF+1000uF 16V, pe pinul de reset pull-up cu 10K. Softul este:

 

/*
Program: Controler ventilator baie, cu LDR
uC Attiny85 8MHz, Optiboot
*/

#include <avr/io.h>
#include <avr/wdt.h>

#define LDR_PIN	A2
#ifdef __AVR_ATtiny85__
#define RELAY_PIN	3
#else
#define RELAY_PIN	13
#endif


#define DELAYON 120*1000		// 2 minute delay on
#define MAXIMUMRUN	3600000

uint32_t cMs = 0;
uint32_t userStartTime = 0;
uint32_t userTotalTime = 0;

void setup() {
	pinMode(LDR_PIN, INPUT);
	pinMode(RELAY_PIN, OUTPUT);	

#ifdef __AVR_ATmega328P__
	Serial.begin(9600);
#endif
	
#ifdef __AVR_ATtiny85__	
  if(MCUSR & _BV(WDRF)){ 
    MCUSR &= ~_BV(WDRF);
    WDTCR |= (_BV(WDCE) | _BV(WDE));
    WDTCR = 0x00;	 
   }
 wdt_enable (WDTO_2S);
 #endif
}
/*--------------------------------------------------------------------------------------------*/
byte readLDR(uint32_t interval, uint16_t cntRead, uint16_t triggerOn = 500, uint16_t histerizis = 50){
	static uint32_t lstRdLDR = 0;
	static uint16_t cntReadLDR = 0;
	static uint16_t readLDRSum = 0;
	static byte result = 0;
	static byte old_result = 0;
	
	if((cMs-lstRdLDR)>interval){			
		if (cntReadLDR < cntRead) {
			readLDRSum += map(analogRead(LDR_PIN),1023,0,0,1023);
			cntReadLDR++;
		} 
		else {
			readLDRSum = (uint16_t)(readLDRSum / cntReadLDR);
			 if ((readLDRSum+histerizis) >= triggerOn) result = 1;
			 if ((readLDRSum-histerizis) <= triggerOn) result = 0;
			#ifdef __AVR_ATmega328P__
				Serial.print(F("cMs: "));	Serial.print(cMs);
				Serial.print(F(", readLDRSum: "));	Serial.print(readLDRSum);
				Serial.print(F(", userStartTime: ")); Serial.print(userStartTime);
				Serial.print(F(", userTotalTime: ")); Serial.println(userTotalTime);
			#endif
			readLDRSum = 0;
			cntReadLDR = 0;			
		}
	 lstRdLDR = cMs;	 
  }
  
  if (old_result != result) {	  
	  if (result) userStartTime = cMs;
	  if (!result) {		  
		  userTotalTime = (cMs-userStartTime)+cMs;
		  if (userTotalTime > (uint32_t)MAXIMUMRUN) userTotalTime = (uint32_t)MAXIMUMRUN; // do not run over 1hour
	  }
	  old_result = result;
  }
  
  
  return result;
}
/*--------------------------------------------------------------------------------------------*/
void loop() {
#ifdef __AVR_ATtiny85__		
	wdt_reset (); //wathdog !
#endif	
	cMs = millis();
	byte presence = readLDR(50UL, 10,500,50);
	byte relState = 0;
	if (((presence) && ((cMs-userStartTime)>= (uint32_t)DELAYON)) || (cMs<=userTotalTime)) relState = 1; else relState = 0;
	digitalWrite(RELAY_PIN, relState);
}

 

Problema este ca se blocheaza adesea uC. Ce v-as ruga este sa va dati o parere referitor la soft, daca ar putea genera o eroare din soft sau se intampla ceva pe cablaj...

Editat de Gilbert Sparios
Link spre comentariu
  • Răspunsuri 8
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Despre hardware e greu sa imi dau cu parerea.

 

Insa, in soft se pare ce RESET-ul nu se face de catre WDT. Uite aici ceva despre WDIE, setare care lipseste din codul tau.

 

Secventa asta:

// Reset the watchdog reset flag
  MCUSR &= ~(1<<WDRF);
  // Start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // Set new watchdog timeout value
  WDTCR = bb;
  // Enable interrupts instead of reset
  WDTCR |= _BV(WDIE);

 

Daca ma insel, neintelegand codul tau, scuze.

Link spre comentariu

O sa dau jos cutia din tavanul fals sa fac experimente. Cel mai probabil e situatia cu conflictul intre optiboot sau ventilatorul de la baie care e dupa releu dar alimentat din acelasi punct cu sursa principala face un emi ceva.. 

 

Trebuie cautat...

Un proiect asa banal..din pacate face figuri...

Editat de Gilbert Sparios
Link spre comentariu

Am revenit cu un update. Am impresia ca uC nu este blocat sau aparent nu este blocat.

Pentru ca citirea LDR o face, si dupa expirarea timpului de 2 minute (<DELAYON>) porneste ventilatorul, insa nu ramane cuplat timpul definit de <userTotalTime> dupa stingerea becului in baie.

 

Nu vad eroarea dar pare o eroare in cod totusi... sau Timer0 pentru millis() pateste ceva...?..

Dupa re-alimentare montaj-ul se comporta normal...o vreme..

 

Link spre comentariu
 if (userTotalTime > (uint32_t)MAXIMUMRUN) userTotalTime = (uint32_t)MAXIMUMRUN; // do not run over 1hour

 

Si

 

if (((presence) && ((cMs-userStartTime)>= (uint32_t)DELAYON)) || (cMs<=userTotalTime)) relState = 1; else relState = 0;

 

Nu prea se impaca as zice eu. In anumite cazuri tu compari valaorea de "MAXIMUMRUN" care este 1 ora cu current millis() ? Pai daca montajul ala odata alimentat functioneaza o ora si currentMillis ajunge peste valoarea 3600000 oare ce se intampla ? In ce conditii poate fi acel " (cMs<=userTotalTime)" adevarat daca tie "millis()" o sa returneze tot timpul valori peste 3600000 ? 

 

Ai niste probleme de logica pe acolo... 

Link spre comentariu

Aparent ai gasit eroarea mea.

 

Astfel ca

if (userTotalTime > (uint32_t)MAXIMUMRUN) userTotalTime = (uint32_t)MAXIMUMRUN; // do not run over 1hour

devine

if (userTotalTime > ((uint32_t)MAXIMUMRUN)+cMs) userTotalTime = ((uint32_t)MAXIMUMRUN+cMs); // do not run over 1hour

 

Multumesc  @Bandi Szasz

Editat de Gilbert Sparios
Link spre comentariu

Destul de greu de urmarit si depanat programul tau.
Daca tot ai numit functia "ReadLDR()" eu zic ca o lasi sa faca numai asta. Sa citeasca de un anumit numar de ori pinul analog si sa returneze valoarea , eventual mapata in interval.
Si sa faci comparatii si decizii in loop() sau in alte functii.


 

Link spre comentariu

Alătură-te conversației

Poți posta acum și să te înregistrezi mai târziu. Dacă ai un cont, autentifică-te acum pentru a posta cu contul tău.
Notă: Postarea ta va necesita aprobare moderator înainte de a fi vizibilă.

Vizitator
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Răspunde la acest subiect...

×   Alipit ca text avansat.   Restituie formatare

  Doar 75 emoji sunt permise.

×   Linkul tău a fost încorporat automat.   Afișează ca link în schimb

×   Conținutul tău precedent a fost resetat.   Curăță editor

×   Nu poți lipi imagini direct. Încarcă sau inserează imagini din URL.




×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări