Vojtěch Vosáhlo
Vytvořené odpovědi
-
AutorPříspěvky
-
Vojtěch VosáhloÚčastník
Pokud to tedy chápu správně, místo použití příkazu switch mám použít vypsaní všech možností podmínkou if
To úplně neříkám. Já použil if pouze protože jsem volal jen jednu funkci, jen kvůli jednoduchosti. Vy můžete nadále používat switch case. Pokud byste chtěl mít kód optimalizovaný na max, dá se použít něco takového:
#include <Adafruit_NeoPixel.h> #include"IRremote2.h" ///Deklarace pouzitych funci void funkce1(); void funkce2(); #define pinIN 4 #define PIN 6 // Parametr 1 = počet pixelů (LED diod) na pásek // Parametr 2 = číslo PINu Arduina // Parametr 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz kmitočet pro pásky s WS2812 LED diodami) // NEO_GRB Pixely jsou zasílány ve formátu GRB Adafruit_NeoPixel pixels = Adafruit_NeoPixel(36, 6, NEO_GRB + NEO_KHZ800); IRrecv dalkoveOvl(pinIN); decode_results vysledek; char pozice; typedef void (* Caller)(); Caller funkce[] = {&funkce1, &funkce2}; ///FUNKCE KTERE CHCETE VOLAT char serial_prikazy[] = {'1', '2'}; ///PRIKAZY KORESPONDUJICI S FUNKCEMI tzn. 1 vola funkce1 int32_t ir_prikazy[] = {0x00FFA25D, 0xFFE21D}; char data; void setup(){ pixels.begin(); Serial.begin(9600); pixels.show(); delay(250); dalkoveOvl.enableIRIn(); } /////////////////////////////////////////////////////////////////////// //////////////FUNKCE KTERE BUDOU VOLANE PRIKAZY ////////////////////// void funkce1(){ dalkoveOvl.resume(); while(!(Serial.available() || dalkoveOvl.decode(&vysledek))) { pixels.setPixelColor(6, pixels.Color(255,255,255)); pixels.show(); delay(1000); pixels.setPixelColor(6, pixels.Color(0,0,0)); pixels.show(); delay(200); pixels.setPixelColor(6, pixels.Color(255,255,255)); pixels.show(); delay(1000); pixels.setPixelColor(6, pixels.Color(0,0,0)); pixels.show(); delay(200); } } void funkce2(){ dalkoveOvl.resume(); while(!(Serial.available() || dalkoveOvl.decode(&vysledek))) { pixels.setPixelColor(16, pixels.Color(255,255,255)); pixels.show(); delay(1000); pixels.setPixelColor(16, pixels.Color(0,0,0)); pixels.show(); delay(200); pixels.setPixelColor(16, pixels.Color(255,255,255)); pixels.show(); delay(1000); pixels.setPixelColor(16, pixels.Color(0,0,0)); pixels.show(); delay(200); } } ///////////////////////////////////////////////////////////////////// void loop(){ if(Serial.available() || dalkoveOvl.decode(&vysledek)){ data = Serial.read(); for(int i = 0; i < sizeof(funkce); i++){ if(data == serial_prikazy[i] || vysledek.value == ir_prikazy[i]){ funkce[i](); } } } }
Prakticky si na začátku zapíšete všechny různé funkce a pak už se jen volají podle příkazů. Je to kratší a nemusíte používat switch case.
Nejdůležitější je deklarovat si na začátku všechny „blikací a svítící“ funkce asi taktovoid funkce1(); void funkce2();
Těch tam může být kolik chce.
Poté si zapíšete příkazy které funkce spouští jako tady: `Caller funkce[] = {&funkce1, &funkce2}; ///FUNKCE KTERE CHCETE VOLAT
char serial_prikazy[] = {‚1‘, ‚2‘}; ///PRIKAZY KORESPONDUJICI S FUNKCEMI tzn. 1 vola funkce1
int32_t ir_prikazy[] = {0x00FFA25D, 0xFFE21D};`V Caller funkce[] jsou zapsány samotné funkce které se budou volat, zapisujete je jako &nazevfunkce. V serial_prikazy[] jsou sériové příkazy které spouští dané funkce tzn. příkaz na 1. pozici spustí funkci na 1. pozici v tom Caller funkce[]. V poli ir_prikazy[] jsou opět korespondující příkazy které spouští funkce. Musí být zapsány jako 0x00vasirkod. Ten kód co jsem přihodil by měl fungovat jako ten váš se switch case nebo if. Schválně zkuste a uvidíme.
Obnovení předešlé animace kdyžtak vyřešíme jestli tohle bude fungovat.
Vojtěch VosáhloÚčastníkZkuste něco takového jako zjednodušený kód. Mělo by to blikat s prvním pixelem pokud zmáčknete CH- nebo pošlete 1. Pokud přijde něco jiného, smyčka by se měla přerušit.
#include <Adafruit_NeoPixel.h> #include"IRremote2.h" #define pinIN 4 #define PIN 6 // Parametr 1 = počet pixelů (LED diod) na pásek // Parametr 2 = číslo PINu Arduina // Parametr 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz kmitočet pro pásky s WS2812 LED diodami) // NEO_GRB Pixely jsou zasílány ve formátu GRB Adafruit_NeoPixel pixels = Adafruit_NeoPixel(36, 6, NEO_GRB + NEO_KHZ800); IRrecv dalkoveOvl(pinIN); decode_results vysledek; char pozice; void setup() { pixels.begin(); Serial.begin(9600); pixels.show(); int delayval = 300; delay(250); dalkoveOvl.enableIRIn(); } void loop() { if (dalkoveOvl.decode(&vysledek)) { detekceKlaves(); dalkoveOvl.resume(); } if (Serial.available() > 0) { pozice = Serial.read(); if(pozice == 1) blikejLed(); } } void detekceKlaves() { if(vysledek.value == 0xFFA25D) { Serial.println("Stisknuto CH-"); blikejLed(); // pauza pro přehlednější výpis delay(500); } void blikejLed(){ dalkoveOvl.resume(); while(!(Serial.available() || dalkoveOvl.decode(&vysledek))){ pixels.setPixelColor(1, pixels.Color(255,255,255)); pixels.show(); delay(1000); pixels.setPixelColor(1, pixels.Color(0,0,0)); pixels.show(); delay(1000); } }
Vojtěch VosáhloÚčastníkOzvu se zase zítra, možná si najde čas i někdo z ostatních a dřív, uvidíte. Já bych asi doporučil jednu věc. Udělejte čistý nový projekt pouze s nejnutnějšími funkcemi na přijímání z IR a Serial a spuštění nějaké jednoduché funkce. Omezte to na co nejmenčí kód, klidně jen něco jako po stisknutí ON na ovladači nebo poslání 1 na port rosviť ledky. Na tomhle zkusíme jak by se mělo postupovat s přerušením smyčky a bude to přehlednější než ten kód co máme teď. Zmenšením kódu taky omezíme prostor na chybu. Držím palce.
Vojtěch VosáhloÚčastníkZkuste za while vložit
dalkoveOvl.resume();
tzn bude to vypadat asi takto: `void nejakyefekt(){
while(neco){
}
dalkoveOvl.resume();
}
`
Pokud to nepojede tak se ozvěte. Zkuste taky poslat odkaz na knihovnu kterou přesně máte, jestli existuje dokumentace, bude to jednoduší.Vojtěch VosáhloÚčastníkMělo by stačit přidat k přerušení seriovou linkou i přerušení IR příjmem. Na začátku kódu máte v podmínce if toto: „dalkoveOvl.decode(&vysledek)“
Vzhledem k tomu že je v podmínce, nejspíše vrátí 1/true/pravda pokud něco přijme a zvládne dekódovat a 0/false/nepravda pokud nic nepřijme nebo nedekóduje.
Do vašeho while by tedy stačilo přidat logický operátor OR v arduinu jako ||. Ten vám dá 1 pokud alespoň jedna vstupní hodnota je 1. Smyčka by tedy vypadala asi taktowhile(!(Serial.available() || dalkoveOvl.decode(&vysledek)))...
Serial.available() se podívá jestli je něco dostupného na sériové lince a dalkoveOvl.decode() zjistí zda něco přijímáme. Pokud nic z tohoto neplatí dostaneme 0 která je vykřičníkem znegovaná na 1 a smyčka běží. Pokud bude ale jedna z možností 1, smyčka se zastaví.Mimo tohle by se dal kód ještě různě optimalizovat ale o tom kdyžtak jindy 😉
Vojtěch VosáhloÚčastníkJak můžete říct že správná odpověď je false? Ten kód koukne na to jestli se 1==1, řekne ano ale pak nic nevrací, tzn na return nikdy nenarazí. Může si teda vrátit co chce.
Řešení je v celku jednoduché. Vždy používat return ve všech částech kde by jste měl. Mnoho IDE by vás to ani nenechalo zkompilovat, vyjela by hláška jako „Not all parts of the code return a value.“ Pokud nic nenastavíte, program si asi dělá trochu co chce.Jinak tu funkce upravená tak aby vždy něco vrátila by vapadala takto ale to asi víte.
boolean TestFunction() { if (true) { return true; break; } return false; }
Pokud to je zakomentované tak samozřejmě nevrátí nic…
Vojtěch VosáhloÚčastníkPokud chcete něco co bude po vybalení fungovat tak vyplatí, pokud si chcete pohrát a trochu ušetřit, asi nevyplatí. Postavit se to dá určitě a řekl bych že bez větších problémů. Bezdrátová komunikace by asi byla přes ESP předpokládám. Co vše to má umět? Záleží taky na tom jak se na to cítíte vy. 😉
Vojtěch VosáhloÚčastníkOtázka spíš na jirku a Zbyška. Když kouknu do schématu, tranzistor v optočlenu je NPN že? Ono se dá NPN tranzistorem spínat tímto způsobem? Celou dobu žiju v tom že musí být na emitoru hlavní zdroj, tzn. VCC nebo GND a na kolektoru je zátěž, to co spínám. Také jsem si myslel že NPN mi povede jen „zemi“ pokud se sepne (je na bázi VCC), a ne VCC. Asi bych tu vůbec neměl být když tohle nevím ale rád se dozvím jak to je.
Vojtěch VosáhloÚčastník1) proč není do knihovny zakomponován přenos jiného formátu než word?
Přiznám se že nevím, skoro určitě vám tu ale někdo odpoví.
2) lze to nějak obejít aby to začalo float přenášet?
Proč teplotu prostě nepředělat na word? Odstranit desetinou tečku tzn. třeba 23,56 => 2356.
Kdyby jste potřeboval posílat floaty univerzálně, a né vždy 2 desetiná místa, dala by se asi bez problému napsat funkce, která by poslala třeba nejdříve dané číslo bez čárky a hned po něm počet des míst. Třeba jako 23,56 => 2356; 2 a nebo rovnou číslo kterým se musí word vydělit aby vznikl původní float: 23,56 => 2356; 100. Tzn 2356/100= 23,56.Tohle je samozřejmě jedno pokud se to dá nějak obejít.
Vojtěch VosáhloÚčastníkNo něco je určitě špatně ale proč hned kupovat nový displej? Zkuste odpájet i2c převodník a řídit displej přes piny na něm. Alespoň zjistíte kde je chyba.
Vojtěch VosáhloÚčastníkDobrý večer,
problém bude nejspíše v tom že máte proměnou teplota inicializovanou jako byte. Vámi použitá knihovna s byty asi neumí pracovat. Zkuste jí změnit na float místo byte. Možná my to nedocvaklo ale nejde vám to vypsat na displeji nebo sériový port a nebo nefunguje ani jedno?Vojtěch VosáhloÚčastníkvojtechu ty zkratky nejsou moc dobre. 1w a uC bych taky lustil ? prosim zkuste se drzet zazite terminologie 1-wire pripadne one-wire a uprocesor.
Za ty zkratky se omlouvám 😀 nalezlo mi toho nějak moc do hlavy.
Vojtěch VosáhloÚčastníkS tím můžu jenom souhlasit, pokud jste s tím moc nedělal tak je to nejlepší řešení. Budu vám držet palce. Kdykoliv se sem můžete obrátit.
Vojtěch VosáhloÚčastníkMimochodem při delších drátových rozvodech pak musíte pracovat i s odporem a kapacitou drátu. Třeba článek zde vše popisuje, kdyby jste se rozhodl jít pro 1wire:
A oprava, na 1wire zběrnici není úplně daný limit, je to dané právě kapacitou a délkami drátů.
Vojtěch VosáhloÚčastníkuC jsem myslel mikroprocesor, něco jako Attiny13/45/85…
Kdybyste šel tou cestou která se jednoduše rozšiřuje, stačilo by do všech místností natáhnout trojlinku – 1. Země 2. Napájení 3. Komunikace (např. ten onewire)Na tuto „síť“ by pak mohlo být připojeno prakticky cokoliv co přes 1wire komunikuje. Tady je ale problém že servo na 1W nepřipojíte…
Tím pádem by se musel do hry přidat právě nějaký mikroprocesor. I Attiny13 (asi 20Kč za kus v ČR) by mělo stačit kdyby vám nevadilo psát v C.
Takže by se vytvořila taková senzorová jednotka.
[Teploměr, servo atd. <—–> uC(konverze z/na 1W) ]<–trojlinka natažená pokoji–> hlavní uC
Kdyby jste pak měl nataženou trojlinku stačí na ní jen „napíchat“ všechna zařízení. To označené [ ] je vaše zařízení které bude připíchnuté na trojlince.
Například dallas (to je snad maxim?) prodává čipy co dělají přímou konverzi I/O na onewire takže k tomu zapojíte třeba tlačítko, píchnete na trojlinku a najednou máte spínač připojený k celému systému.
Pokud vím tak max počet zařízení je 255.Rozhodně se vyplatí vytvořit něco rozšiřitelného pokud plánujete cokoliv přidávat.
Vojtěch VosáhloÚčastníkDůležitá věc u něčeho takového je rozšiřitelnost. Vy vlastně natáhnete tolik kabelů kolik máte serv. Pokud jste si 100% jistý že to takhle zůstane, je to nejlepší řešení, a nejjednodušší. Pokud by ale byla šance že budete někdy chtít něco přidat, mohl byste mít nouzi o kabely… Tady by poté bylo nejlepší mít u každého serva/senzoru uC který by vše sjednocoval na jednu datovou linku, třeba 1wire. Na to můžete pak přidávat zařízení prakticky bez omezení. Je to jen něco nad čím se zamyslet.
Vojtěch VosáhloÚčastníkMůžu vědět jak budete se sonzory a servy komunikovat?
Kabel/bezdrátově, protokly…Vojtěch VosáhloÚčastníkNejdříve připojení bez wifi. Na to se dá esp nakonfigurovat jako AP. Ono si pak vytvoří vlastní síť a vy se na ní můžete telefonem připojit. Na netu koukejte po esp as AP.
To druhé je taky poměrně proveditelné, musel byste mít rozchozený DNS. Na to se taky dají na netu najít řešení dokonce i zdarma.
Vojtěch VosáhloÚčastníkPina má jen jedny a jsou vyvedeny 2x, nic specialniho se nastavovat nemusí. Musí být připojeny RX na TX a Tx na RX, jak už psal Zbyšek. Proč používáte kód pro 2 sériové porty když máte jen jeden jak jste psal?
Vojtěch VosáhloÚčastníkTo co chcete je prostě jednoduchý kód pro serial. Dá se najít kdekoliv na webu. Chápu že jste začátečník, to jsme byli všichni ale stačí hledat. Když něco nevím, skočím na https://www.arduino.cc/en/Reference/ a prostě si to najdu třeba i s ukázkovým kódem.
Ukázka pro serial println je: `/*
Analog inputreads an analog input on analog in 0, prints the value out.
created 24 March 2006
by Tom Igoe
*/int analogValue = 0; // variable to hold the analog value
void setup() {
// open the serial port at 9600 bps:
Serial.begin(9600);
}void loop() {
// read the analog input on pin 0:
analogValue = analogRead(0);// print it out in many formats:
Serial.println(analogValue); // print as an ASCII-encoded decimal
Serial.println(analogValue, DEC); // print as an ASCII-encoded decimal
Serial.println(analogValue, HEX); // print as an ASCII-encoded hexadecimal
Serial.println(analogValue, OCT); // print as an ASCII-encoded octal
Serial.println(analogValue, BIN); // print as an ASCII-encoded binary// delay 10 milliseconds before the next reading:
delay(10);
}Řeknu si že ale nechci posílat data přečtená z analogu ale jen AT+XXXXXX příkaz. Tak si kód prostě a jednoduše přepíšu, smažu čtení analogu a několik println vyměním za jedno. Vznikne mi něco takového:
void setup() {
// open the serial port at 9600 bps:
Serial.begin(9600);
}void loop() {
Serial.println(„AT“);
delay(1000);
}
`Doufám že chápete kam tím mířím. Prostě učit se, učit se, učit se 😉
Vojtěch VosáhloÚčastníkTakže máte připojený RX modulu na TX arduina a obráceně? Možná by bylo lepší dát si rx a tx na 2 obyčejné piny arduina. Pokud to tak uděláte, můžete použít hlavní RS232 na komunikaci s PC. To by bylo asi lepší. Pak napište na jaké piny je to připojeno a já zkusím vyflusnout nějaký kód.
Vojtěch VosáhloÚčastníkJediné co potřebuje kdokoliv kdo se tu bude podílet vědět je jaký je pinout shieldu. Tzn. kam vede RX a TX ESP. Tohle prostě musíte zjistit vy. Proměřte to, najděte na netu obrázek ESP 12 a proměřte na jaký pin duina jdou. Pak se tu dá něco vymýšlet. Pokud tu už někdo zmiňoval jaké piny to jsou tak mě tam odkažte ale já si nevšiml…
Vojtěch VosáhloÚčastníkJo tohle je psané na megu. Moje chyba. Vemte kód odsud: https://www.arduino.cc/en/Tutorial/SoftwareSerialExample
Vojtěch VosáhloÚčastníkKód od MilosD napsaný výše na této stránce.
Vojtěch VosáhloÚčastníkTrochu teď nevím kde je problém. Zkoušel jste kód uvedený výše? Stačí zjistit které piny shieldu jsou připojeny na TX a RX modulu, v arduinu na ně pak nastavíte software serial a pošlete nějaký ukázkový příkaz. Prakticky stejně jako v kódu nahoře.
Vojtěch VosáhloÚčastníkPřesně, knihovna by měla jít bez problému osekat. Možná by pro vás ale mohlo být jednoduší zkopírovat jen nějaké ty funkce a na import knihovny se úplně vybodnout. O ADC převodníku na čipu nic nevím, tedy maximálně o 8mi bitovém, kdyžtak mě odkažte tam kde jste to našel.
Vojtěch VosáhloÚčastníkZkuste se podívat třeba na toto: https://www.arduino.cc/en/Tutorial/TFTGraph
Jinak když dáte vyhledat „arduino plot graph on TFT“ vyleze mnoho výsledků.
Mimo to se zkuste podívat na toto fórum na téma „Řízení peletového kotle,“ i když to není přesně váš případ, třeba načerpáte další cenné informace.Držím palce
Vojtěch VosáhloÚčastníkPřesně tak. Měla byste mít obvod stejný jako u arduina tzn. i s uzemněním + by se hodil ještě rezistor na ochranu pinu před velkými proudy. Sepnutím spínače připojujete VCC rovnou na pin! Mělo by to být něco jako na tomto obrázku.
Attachments:
Vojtěch VosáhloÚčastníkPokud jde o komplexní čísla, stálo by za to podívat se třeba na toto: http://playground.arduino.cc/Main/ComplexMath
Vojtěch VosáhloÚčastníkMohl by být problém třeba s tím že pokud je spínač nespojený, pin „lítá“ -> neni ani na 1 ani na 0. Chtělo by to tedy rezistor jako máte u arduina. Taky bych ještě přidal jeden rezistor mezi tím spínačem a pinem aby omezil proud který se dostane na pin jak u arduina, tak u shieldu.
-
AutorPříspěvky