Zbyšek Voda
Vytvořené odpovědi
-
AutorPříspěvky
-
Zbyšek VodaÚčastník
Ne, když chcete, aby Arduino něco dělalo, musíte ho naprogramovat…
O displejích viz třeba tady: http://dontbuyjustmake.blogspot.cz/2015/01/reusing-your-ancient-mobile-phone-lcd.html
Zbyšek VodaÚčastníkMáte pravdu, pardon. Návod nesepíšu, protože jsem to nikdy nedělal a ani se v dohledné době nechystám 🙂
Zkuste se kouknout třeba sem
http://www.instructables.com/id/ESP8266-OTA-LUA-With-WEB-UI-MANAGEMENT-Nodemcu-Fir/?ALLSTEPSa sem
http://www.instructables.com/id/ESP8266-WiFi-File-Management/Takto se dá do ESP posílat přes prohlížeč zdrojáky ve skriptovacím jazyku LUA.
Zbyšek VodaÚčastníkZačal jsem to zkoumat a je to celkem zajímavý problém.
Zkusil jsem udělat úplně jednoduchou non-void funkci, která ale, stejně jako u vás, nic nevrací. Ta funkce vypadá takto:
#include <stdint.h> uint8_t fce(){ } int main(){ uint8_t a = fce(); return 0; }
Použil jsem uint8_t, protože boolean je vlastně „převlečený“ typ uint_8 – viz:
typedef uint8_t boolean;
Když tento miniprogram proženu přes kompilátor avr-gcc a zadám přepínače pro výstup v assembleru, získám kód níže. Příkaz pro spuštění kompilace je takovýto (jsem na MacOS):
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-gcc -S main.c
.file "main.c" __SP_H__ = 0x3e __SP_L__ = 0x3d __SREG__ = 0x3f __tmp_reg__ = 0 __zero_reg__ = 1 .text .global fce .type fce, @function fce: push r28 push r29 in r28,__SP_L__ in r29,__SP_H__ /* prologue: function */ /* frame size = 0 */ /* stack size = 2 */ .L__stack_usage = 2 /* epilogue start */ pop r29 pop r28 ret .size fce, .-fce .global main .type main, @function main: push r28 push r29 push __zero_reg__ in r28,__SP_L__ in r29,__SP_H__ /* prologue: function */ /* frame size = 1 */ /* stack size = 3 */ .L__stack_usage = 3 rcall fce std Y+1,r24 ldi r24,0 ldi r25,0 /* epilogue start */ pop __tmp_reg__ pop r29 pop r28 ret .size main, .-main .ident "GCC: (GNU) 4.9.2"
K pochopení toho, co se děje, stačí najít řádek
std Y+1,r24
. Toto je instrukce v assembleru (viz . Slouží k tomu, že se někam do paměti na adresu danou Y+1 (proměnná a v programu) uloží hodnota z registru r24. Když se ale na program podíváte, do tohoto registru se předtím nic neukládá, ani se nenuluje, takže je hodnota nedefinovaná.Tento příklad je zjednodušený, v případě při kompilaci pro Arduino dojde k připojení několika dalších funkcí. Pro ilustraci je to ale myslím dobré 🙂
Podle mě tedy dojde k tomu, že při kompilaci na Linuxu se ještě přidá instrukce pro vynulování registru r24. Je to ale jenom teorie. Můžete vyzkoušet, docela by mě zajímalo, jestli ten assemblerový kód vypadá stejně 🙂
Zbyšek VodaÚčastníkDobrý den, možná by to šlo, ale asi to nebude úplně přívětivé. Programování na iOS je popsané třeba tu: http://www.arduinocode.info .
Také by to asi šlo pomocí OTA přes prohlížeč. K tomu byste potřeboval počítač jen při prvotním nahrání a potom už by to mělo jít přes prohlížeč více o OTA zde: http://esp8266.github.io/Arduino/versions/2.0.0/doc/ota_updates/ota_updates.html
Zbyšek VodaÚčastníkDobrý den, mě ta otázka přijde položená docela jasně 🙂
Pouštím se teď na trochu tenký led, tak snad neplácnu nějakou blbost.
Podle mě jde o to, že norma C++ nevynucuje návrat hodnoty z funkce pomocí return (i když tato funkce není void).Potom tedy závisí na kompilátoru, jak si s tím poradí. Použitý kompilátor pro Arduino je avr-gcc, který se ale asi na obou platformách chová trochu odlišně (právě v takovýchto normou nedefinovaných případech).
Podle mě může dojít ke dvěma možnostem:
1) Na linuxu je defaultní hodnota z funkcí bez return nulová, na Windows nenulová.
Tato možnost ale asi není moc pravděpodobná.2) V https://gcc.gnu.org/wiki/avr-gcc píší, že jednobytové hodnoty se vrací pomocí registrů (ATmega v Arduinech je většinou 8-bitová, takže má i 8-bit registry). Boolean je jenom jiné pojmenování pro bezznaménkové osmibitové číslo, takže se asi vrací v registrech. A právě registry v tom podle mě dělají ten rozdíl – na linuxu se kompilátor chová tak, že registr použitý k návratu vynuluje, kdežto na Windows ne. Díky tomu v registru zůstane hodnota, která už tam byla před voláním funkce (a s největší pravděpodobností je nenulová), takže pak dostanete odpověď OK.
Aspoň takto si to vysvětluji.
Použití
if (Testfunction())
je v pořádku. Můžete si představit, že kompilátor toto vidí jakoif (Testfunction() != 0)
.Zbyšek VodaÚčastníkDobrý den, asi úplně nejjednodušší cesta je použít nějaký oddělovač, který vložíte vždy mezi dvě čísla – třeba byte s hodnotou 255 (0b11111111), popřípadě možná vhodnější 0. Vždycky čekáte, dokud nepřečtete znak s hodnotou 0 a potom přečtete dva byty.
Tato metoda má své mouchy – třeba si musíte ošetřit situaci, kdy i datový být má hodnotu oddělovače (0, popř. 255). Napadá mě třeba k byte před odesláním vždy přičíst 1 – potom se byte s hodnotou 0 v datových bytech nemůže vyskytnout. Po přijetí 1 zase odečtete. Tam je ale zase problém s přetečením.
Dalším způsobem by mohlo být použít redundanci – prostě byte dat pošlete vždycky dvakrát za sebou (například).
Nebo zkusit použít nějaký standardizovaný formát dat – JSON, CSV apod… To už je ale trochu „s kanonem na vrabce“ (viz http://www.zive.cz/clanky/pojdme-programovat-elektroniku-jak-to-ze-je-prumerna-webova-stranka-stejne-velka-jako-doom/sc-3-a-185860/default.aspx).
Výběr vhodného protokolu řeší například zde: http://forum.arduino.cc/index.php?topic=195224.0.
Zbyšek VodaÚčastníkDobrý den, program nemůže nalézt knihovnu GLIBC_2.11 (viz error).
Zde řeší podobný problém pro Ubuntu: http://askubuntu.com/questions/421642/libc-so-6-version-glibc-2-14-not-found
Mělo by stačit updatovat požadovanou knihovnu.
Zbyšek VodaÚčastníkDobrý den,
s tím shieldem se vám to bude jenom jednodušeji zapojovat. Jinak je to jedno 🙂Jen si dejte pozor na to, abyste měla dostatečné napájení. Na stránce píší, že pracovní proud je 400mA, což by Arduino z jeho 5V pinu nemuselo zvládnout.
Zbyšek VodaÚčastníkNajděte si složku, kde máte staženou knihovnu Exosite a v ní si otevřete soubor Exosite.h v nějakém textovém editoru. Hned na začátku programu najděte řádek
#include <WiFi.h>
a zakomentujte ho.Nejsem si jistý, jestli takto bude program fungovat, ale kód se zkompiluje bez chybových hlášek. Zkuste to a uvidíme 🙂
Zbyšek VodaÚčastníkDobrý den, jak se projevuje to „zabití sériové linky“?
Jde také o to, jestli odešel pouze převodník USB-Serial na desce, nebo přímo obvod starající se o sériovou linku v čipu.
Zbyšek VodaÚčastníkPodle té chyby to opravdu vypadá, že bude chyba v knihovně. Někde tam asi dochází k tomu, že se nějaký soubor vloží dvakrát – odsud také chyba „redefinition of classs…“.
Ještě pro jistotu prosím pošlete použitý kód, ale tím to asi nebude.
Zbyšek VodaÚčastníkMáte pravdu, tohle fórum není ideální.
S převodem jsme uvízli na mrtvém bodě.Taková teoretická otázka – jak moc by bylo user-unfriendly, kdybychom začali phpBB fórum úplně na novo a tohle fórum udělali jenom read-only?
Zbyšek VodaÚčastníkNení zač, mějte se 🙂
Zbyšek VodaÚčastníkDobrý den, můžete si udělat třeba nějaké počitadlo.
Kód by pak mohl vypadat například takto (předpokládám, že chcete získat 5 znaků).
int poc = 0; String zadano; char znak; char menu; void setup() { Serial.begin(9600); } void loop() { while (Serial.available()) { znak = Serial.read(); if (znak < 32 || znak > 126) continue; //přeskočí znaky mimo rozumný rozsah (konec řádku...) zadano.concat(znak); poc++; Serial.println(zadano); } if (poc >= 5) { if (zadano == "HELP") menu = 'H'; else menu = '0'; switch (menu) { case 'H': Serial.println(" //================================================\\"); Serial.println(" ||================================================||"); Serial.println(" ||Vypis prikazu ||"); Serial.println(" ||================================================||"); Serial.println(" ||COSI popis instrukce jshfjashfjsah ||"); Serial.println(" ||================================================||"); Serial.println(" \\================================================//"); default: delay(5); } poc = 0; zadano = ""; } }
Zbyšek VodaÚčastníkPošlete kód 🙂
Zbyšek VodaÚčastníkPojďme tedy pokračovat dál 🙂 Koukám na dokumentaci, tak snad ji dobře chápu. (http://playground.arduino.cc/Code/Keypad)
Prozkoumejme pořádně funkci keypadEvent.
void keypadEvent(KeypadEvent eKey){ for (int i =0; i = 5; i++){ admpw[i] = keypad.getState(); Serial.println(admpw[i]); } }
Ta je zavolána kdykoliv, když dojde ke změně stavu klávesy (uvolnění, stisknutí).
Funkce getState() vrací hodnotu podle toho, co se s keypadem děje – vrací hodnoty
IDLE, PRESSED, RELEASED a HOLD. Vy tedy budete ve funkci keypadEvent testovat, jestli je getState() rovna PRESSED a poté zapisovat hodnotu stisknuté klávesy do pole admpw[] na patřičné místo (další v pořadí).Takže bych postupoval následovně: vytvořte si na začátku programu proměnnou
int pos = 0;
, která bude udávat pozici načteného znaku. Při stisknutí tlačítka dojde k uložení stisknutého tlačítka do pole admpw na index pos a navýšení proměnné pos o 1. Musíte si také pohlídat, aby pos měla hodnoty 0 – 4. To se dá zařídit operátorem modulo – %.void keypadEvent(KeypadEvent eKey){ if(keyboard.getState == PRESSED){ admpw[pos] = keyboard.getKey(); pos = (pos + 1) % 5; } }
Takhle by to podle mě mohlo jít 🙂
Zbyšek VodaÚčastníkDobrý den, ve funkci keypadEvent máte podivnou ukončovací podmínku cyklu for.
Máte tam:for (int i =0; i = 5; i++)
Tedy cyklus probíhá, dokudi = 5
. V každém průchodu se tedy do i přiřadí hodnota 5, je vyhodnocena jako true a cyklus opakuje znova – tedy se zacyklí.Asi je to překlep a chtěl jste napsat
i < 5
🙂Pokud byste chtěl testovat rovnost, tak musíte použít operátor
==
,=
je přiřazení hodnoty do proměnné.Zbyšek VodaÚčastníkDobrý den, já mám dobrou zkušenost s tímto převodníkem http://www.hwkitchen.com/products/logic-level-converter/. Použil jsem ho v několika projektech a funguje bez problému.
Zbyšek VodaÚčastníkŘešení: V době programování Arduina odpojit cokoliv, co je připojeno na piny RX a TX (0 a 1). Jak psal Dreamer.
Zbyšek VodaÚčastníkPopřípadě ten přeposílač mezi sériovými linkami (Serial a Serial1) vypadá takto:
void setup() { Serial.begin(9600); Serial1.begin(9600); } void loop() { while (Serial1.available()) { Serial.write(Serial1.read()); } while (Serial.available()) { Serial1.write(Serial.read()); } }
ESP pak nepřipojujete na piny RX a TX, ale RX1 a TX1 – RX a TX jsou totiž napojené přímo na převodník z PC. Více linek ale mají jenom některé desky – jak jsem psal – Arduino Mega, Leonardo…
Zbyšek VodaÚčastníkDobrý den,
musíte mít připojené RX na TX a TX na RX (ne RX na RX apod.)Potom už jenom přes sériovou linku (Serial.println…) posíláte do ESP AT příkazy (za předpokladu, že máte v desce původní firmware). At příkazy viz: http://www.pridopia.co.uk/pi-doc/ESP8266ATCommandsSet.pdf.
Pokud máte Arduino s více sériovými linkami (Mega, Leonardo, …), můžete do něj nahrát program, který bude sloužit jenom jako přeposílatel mezi PC a ESP, kterému přes Serial Monitor můžete posílat AT příkazy, ozkoušet si je a až potom je natvrdo napsat do programu. Pěkný návod je například zde: http://dalpix.com/blog/connecting-your-arduino-wifi-esp-8266-module
Zbyšek VodaÚčastníkDobrý den,
zrovna Sparkfun má dokumentaci zpracovanou opravdu kvalitně 🙂
Tady je například stránka produktu: https://www.sparkfun.com/products/9721Najdete tam odkaz na Datasheet i ukázkový kód.
Zbyšek VodaÚčastníkO té možnosti ovládání zařízení vzdáleně jsem psal tady: https://bastlirna.hwkitchen.cz/programovani-webovych-rozhrani-pro-arduino/.
Zařízení vystupuje v roli klienta a periodicky se připojuje na stránku a zkoumá například nějaký text – když narazí na L, tak motor vypne, když na H, zapne apod.
Stejně může fungovat informování o jeho stavu – když se stav změní, zaloguje se změna na stránku.
Zbyšek VodaÚčastníkPostup je sepsaný v odkazech, které jsem vám poslal.
Zbyšek VodaÚčastníkMáte dvě možnosti. Buď ESP budete používat ve stavu, v jakém vám přišlo, nebo ho přeprogramujete.
Pokud ho chcete používat v původním stavu, ovládá se ESP pomocí AT příkazů. AT příkazy se do ESP posílají přes sériovou linku a můžete jimi například říct, kam se má modul připojit, v jakém módu má pracovat a další. Tato metoda vám dovolí s modulem dělat všechny potřebné základní operace.
Docela pěkně je tento postup popsán například zde: http://www.instructables.com/id/Using-ESP-01-and-Arduino-UNO/?ALLSTEPS, popřípadě tady: https://create.arduino.cc/projecthub/ROBINTHOMAS/programming-esp8266-esp-01-with-arduino-011389.Druhá možnost je programovat přímo ESP, ale to pak nepotřebujete Arduino a nevím, jestli to ve vašem konkrétním shieldu lze 🙂
Jak na to je vidět například zde: https://www.youtube.com/watch?v=P_ecAFpUADU.Zbyšek VodaÚčastníkDobrý den, asi bude problém v tom, že není WiFi shield jako Wifi Shield 🙂
On totiž oficiální Arduino WiFi shield (https://www.arduino.cc/en/Main/ArduinoWiFiShield) je úplně jiný než ten, který jste použil.Na vašem shildu je modul ESP8266, takže spíš hledejte „Arduino and ESP8266“ 🙂
Zbyšek VodaÚčastníkDobrý den, jakou desku máte?
Nemůžou se vám tlouct piny použitých periferií?Třeba deska Arduino Leonardo používá pin 2 pro I2C komunikaci.
Zbyšek VodaÚčastníkJestli se nepletu, tak se toto u Leonarda občas stane.
Zkuste do něj nahrát nějaký jednoduchý kód, třeba jenomvoid setup(){} void loop(){}
a to tak, že před stisknutím „Upload“ v IDE zmáčkněte na desce tlačítko Reset, až poté dejte Upload v IDE. Jakmile se dole ve stavovém řádku IDE objeví Uploading, tak tlačítko reset pusťte.
Zbyšek VodaÚčastníkDobrý den, tak ještě zkuste nasdílet váš kód 🙂
Zbyšek VodaÚčastníkNení zač. Pokud se vám teď nechce prokousávat teorií, můžete použít kód z té sekce Interrupt Example (the Encoder interrupts the processor). Uses both Interrupt pins. Proměnná encoder0Pos udává polohu enkodéru – ve vašem případě plní funkci vaší proměnné counter.
-
AutorPříspěvky