Komplettera fungerande Arduion kod

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Drivmedel
Inlägg: 56
Blev medlem: 29 oktober 2011, 13:40:18
Ort: Lund Södra Sandby

Komplettera fungerande Arduion kod

Inlägg av Drivmedel »

Om if satsen "if(buf[0]=='1')" är sann efter ett bestämt antal mottagningar i följd vill jag sätta utgången on.
Och
Om if satsen "if(buf[0]=='0')" är sann efter ett bestämt antal mottagningar i följd vill jag sätta utgången off.
Hur skall koden skrivas enklast?
__________________________________________________________________________________
Här är koden som jag har den nu, som jag inte själv skrivit.

#include <VirtualWire.h>
#include <VirtualWire_Config.h>
void setup()
{
vw_set_ptt_inverted(true); // Required for DR3100
vw_set_rx_pin(12);
vw_setup(1200); // Bits per sec
pinMode(2, OUTPUT);

vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;

if (vw_get_message(buf, &buflen)) // Non-blocking
{
if(buf[0]=='1'){
digitalWrite(2,1);

}
if(buf[0]=='0'){
digitalWrite(2,0);

}

}
}
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Komplettera fungerande Arduion kod

Inlägg av johano »

Inte säker på att jag fattat kravspecen rätt, men kanske en räknare som räknar upp ett för varje if(buf[0]=='1') och ner ett för varje if(buf[0]=='0').
Om räknaren når ett visst värde X så sätts utgången 'on' och om den når 0 så sätts utgången 'off'.
Du vill nog också ha en kontroll att räknaren inte räknar till mer än X eller mindre än 0.

/johan
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Komplettera fungerande Arduion kod

Inlägg av Mr Andersson »

Två räknare, en för av och en för på. Båda startar på 0.
Om buf är 1, öka på-räknaren med 1. Sätt av-räknaren till 0.
Om buf är 0, öka av-räknaren med 1. Sätt på-räknaren till 0.
Om buf är något annat, sätt båda räknarna till 0.
Om på-räknaren är lika med X, sätt utgången hög.
Om av-räknaren är lika med X, sätt utgången låg.
Drivmedel
Inlägg: 56
Blev medlem: 29 oktober 2011, 13:40:18
Ort: Lund Södra Sandby

Re: Komplettera fungerande Arduion kod

Inlägg av Drivmedel »

Jo du har fattat det rätt. Har lite svårt för att förstå hur jag skall skriva tillägget programsnutten.
Vill du hjälp mig är jag tacksam.
Har skrivit i ASEMBLER och Basic för många år sedan, har svårt att förstå det här högnivå språket, kan kanske bero på att jag inte är någon ungdom längre.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Komplettera fungerande Arduion kod

Inlägg av datajompa »

Kod: Markera allt

#include <VirtualWire.h>
#include <VirtualWire_Config.h>
#define ever (;1;)
void setup()
{
	vw_set_ptt_inverted(true); // Required for DR3100
	vw_set_rx_pin(12);
	vw_setup(1200); // Bits per sec
	pinMode(2, OUTPUT);

	vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
	uint8_t buf[VW_MAX_MESSAGE_LEN];
	uint8_t buflen = VW_MAX_MESSAGE_LEN;

	int count0 = 0, count1 = 0;
	const int countThreshold = 10;

	if (vw_get_message(buf, &buflen)) // Non-blocking
	{
		switch(buf[0]) {
			case '1': {
				count0 = 0;
				if(countThreshold >= count1)
					count1++;
				if(countThreshold == count1)
					digitalWrite(2,1);
			} break;
			case '0': {
				count1 = 0;
				if(countThreshold >= count0)
					count0++;
				if(countThreshold == count0)
					digitalWrite(2,0);
			} break;
			default: {
                                /* avkommentera om det bara ska vara en helt obruten följd av ett visst tal som ändrar porten */
				/* count0 = count1 = 0; */
			} break;
		}
	}
}
int main(void) {
   setup();
   for ever {
      loop();
   }
   return 0;
}
Drivmedel
Inlägg: 56
Blev medlem: 29 oktober 2011, 13:40:18
Ort: Lund Södra Sandby

Re: Komplettera fungerande Arduion kod

Inlägg av Drivmedel »

Tack för hjälpen Datajompa.
Det hade jag inte klarat själv, det var lite problem vilket gav mig mer lärdom.
Fick flytta detta
"int count0 = 0, count1 = 0;"
"const int countThreshold = 10;" till innan setup
Skall ha "Pilemojen" till att blockera eller ställa ner strömmen i min laddbox till min BMWi3a när min frånluftsvärmepump IVT490 laststyr.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Komplettera fungerande Arduion kod

Inlägg av datajompa »

Ok, det låter då isåfall som att du vill ha en mer robust lösning än vad man kunde tro på din problembeskrivning i första inlägget. Är du verkligen säker på att det räcker med att räkna ASCII-värdena '1' och '0' för att tolka styrsignalerna från värmaren eller vad det nu är som skickar en digital signal? Om det är höga strömmar och en fin bil inblandat så vill du inte ha en hackig lösning.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Komplettera fungerande Arduion kod

Inlägg av datajompa »

Drivmedel skrev: Fick flytta detta
"int count0 = 0, count1 = 0;"
"const int countThreshold = 10;" till innan setup
Ja, det är ju för att jag skrev en rejäl bug! Det skulle ha stått static int count0 = 0, count1 = 0; annars funkar det ju inte, om man inte gör dom globala som du gjorde. static gör att variabeln hamnar på heapen och därför inte initialiseras mer än vid deklarationen, så att count0 och count1 i detta fall då inte nollställs vid varje anrop eftersom de deklarerats på stacken som jag råkade göra. Däremot spelar det ingen roll var countThreshold deklareras. Jag får erkänna att jag inte testade koden alls innan jag skrev inlägget.
Drivmedel
Inlägg: 56
Blev medlem: 29 oktober 2011, 13:40:18
Ort: Lund Södra Sandby

Re: Komplettera fungerande Arduion kod

Inlägg av Drivmedel »

Ytterligare ett tack! ny kunskap för mig.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Komplettera fungerande Arduion kod

Inlägg av Icecap »

Nja - att en lokal variabel tas från stacken betyder INTE att den initialiseras! Det allokeras stack-plats ("här har du adressen, gör var du vill") men ingen initiering sker varför man ska göra det i rutinen om det behövs.

Men oftast är dessa lokala variabler ju initierat i form av att värden hämtas in och räknas på varefter värdet kastas ner i den lokala variabel. Men man kan lita på att en icke-static variabel alltid har ett godtyckligt värde vid rutinens start!

Vill man att värdet ska ligga kvar "i rutinen" till senare användning ska den helt rätt deklareras som 'static' i rutinen och en initiering kan då ske på det vis som datajompa beskriver.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Komplettera fungerande Arduion kod

Inlägg av datajompa »

Icecap skrev:Nja - att en lokal variabel tas från stacken betyder INTE att den initialiseras!
Det skrev jag ju inte heller, du tolkar in den implicita betydelsen i min dåliga formulering. Poängen var att den eventuella initialiseringen sker varje gång blocket körs om man inte deklarerar variabeln som static. Sedan kan jag inte C-specifikationen tillräckligt väl för att veta om det verkligen är ett krav att statiska variabler läggs på heapen. I mikrokontrollers kanske det finns goda anledningar att inte göra så. Static måste för övrigt vara ett av de mest vilseledande valen av terminologi som gjorts.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Komplettera fungerande Arduion kod

Inlägg av lillahuset »

Static är en alldeles utmärkt benämning. Precis som volatile.

Du kan deklarera en static var du vill i koden och den är "privat" i den funktion eller fil du deklarerat den i. Den initieras till 0 (eller till ett värde, tror jag, om du skriver tex "int datajompa = 45") vid start. Den behåller sitt värde mellan funktionsanropen om den är definierad i en funktion. Sedan, var kompilatorn lägger den, spelar inte så stor roll, programmerar man en mikroprocessor av någorlunda modern typ brukar den hamna i .data.

Volatile, eller rörlig eller flyktig, är en bra variabeltyp om man vill berätta för kompilatorn att "det här fattar du inte, ge fan i att optimera". Användningsområden är tex I/O-portar och variabler uppkräkta av diverse interruptrutiner. Budskapet är, försök inte gissa något om den här variabeln.

datajompa: Den bistra sanningen är att i C så är det bara skräp på stacken när man anropar en funktion, naturligtvis bortsett från parametrar man skickar till funktionen. Lokala variabler brusar mer än man vill.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Komplettera fungerande Arduion kod

Inlägg av Icecap »

datajompa: "Poängen var att den eventuella initialiseringen sker varje gång blocket körs om man inte deklarerar variabeln som static."

Ja, om du deklarerar en temporär variabel med en initiering blir den såklart initierat i enlighet med detta. Exempel:

Kod: Markera allt

int Some_Function(int A_Value)
  {
  int Calc = 0; // Deklarerat med initiering
  ... // Göra grejer
  }
Detta motsvarar direkt:

Kod: Markera allt

int Some_Function(int A_Value)
  {
  int Calc; // Deklarera variabeln från stacken, värdet är okänd men ganska säkert fel till vad man avser att göra
  Calc = 0; // Initiera värdet i variabeln
  ... // Göra grejer
  }
Av den grund initierar jag ENBART static-värden så att tydligheten i koden kvarstår.
Skriv svar