Fiúk ! Megkaptam a TavIR írásos anyagát , ami sokat segített . így már egészen jó hőmérséklet regisztrálót készítettem, csak nem tudom elmenteni az adatokat . A soros plotteren 500 pontot tudok egyszerre látni, a többi pedig elvész . Kicsúszik a képernyőből és folyton mennie kell a laptopnak.
Mindenkinek köszönöm aki segített a mérések átlagolásában . Most már jól megy , de legtöbbet az árnyékolt vezeték és a 100nF kerámia kondik segítettek.
ARDUINO 1.0.1 programon fordítom , ez állítólag stabilabb, de nincs soros plotter.
ARDUINO 1.8.5 ha plotterezek erre töltöm fel és már van plotterem .
A kártya olvasót csak 1.0.1.- en próbáltam.
Ezek a cuccaim vannak :
Most már két hete tökölődöm vele, de még a kártyát sem tudtam megnyitni .
A képeket azért tettem fel , hogy semmi ne kerülje el a figyelmünket.
A PROGRAM : sok kommentárt kiszedtem belőle
,-,---,-,-,-,-,-,-,-,-
/* EZT A PROGRAMOT INNEN KOPPINTOTTAM : MINDENKINEK OTT VAN A SAJÁT GÉPÉN : ... ARDUINOlibrariesSDexamplesDataloggerDatalogger.ino MINDENKINEK OTT VAN A SAJÁT GÉPÉN !!
The circuit: * analog sensors on analog ins 0, 1, and 2 * SD card attached to SPI bus as follows: ** MOSI - pin 11 ** MISO - pin 12 ** CLK - pin 13 ** CS - pin 4 */
#include <SD.h> const int chipSelect = 10; // EZT ÉN ÁLLÍTOTTAM " 10.-re " ELŐTTE 4.-es VOLT !!
void setup() { Serial.begin(9600); while (!Serial) { ; } Serial.print("Initializing SD card..."); pinMode(10, OUTPUT); // ITT MÁR " 10.-es " VOLT, NEM BABRÁLTAM !! if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); return; } Serial.println("card initialized."); }
void loop() { String dataString = "";
for (int analogPin = 0; analogPin < 3; analogPin++) { int sensor = analogRead(analogPin); dataString += String(sensor); if (analogPin < 2) { dataString += ","; } }
- SS és a CS az teljesen ugyanaz , csak másképpen jelölik a kártyaolvasón
- SCK az egyenlő órajellel
- a program elején " const int chipSelect = 10 " 4.-es volt amitén 10.-re változtattam . A MEGA.-n
ez D53 lábnak felel meg , UNO.-n pedig D10.-nek.
- Valahol azt olvastam , hogy csak 2GB.-ig kezeli a kártyát , de ennek a YouTube.-n ellentmondtak , mert úgy vettek fel 32GB.-re mint a szél.
- a kártyákat FAT12 vagy F16-ra kell formázni : nekem a win7 csak a FAT és FAT32-öt kínálta, így a FAT.-ot
használtam. Gondolom ez lehet a FAT16
- Van 20MHz.-s kétsugaras szkópom, de nem gondolom , hogy ez rajtam segítene . Valószínű csak az órajelet látnám. De ha van ötlet ezt is megpróbálhatom.
Egyelőre meg sem nyitja a kártyát .
Ez csak egy prospektus, ennyi van a képernyőn , persze ez fut egész héten :
opning datalog.txt error opening dXW±½¹Initializing SD card...Card failed, or not present error opening datalog.txt error opening datalog.txt error opening datalog.txt
Nem tudok angolul , de ez annyi , hogy hiba a text fájl megnyitásakkor.
Próbáltam mindkét új kártyaolvasóval.
Van egy formázott kártyám 2GB és egy új 4GB, mindkettőt próbálta a laptopban hibátlanok.
Gondolom 2 rossz kártyaolvasó nem lehet egy háztartásban.
Arra van recept, hogy hova kell másolnom a fájlt , vagy lehet bárhol a winchesteren ?
Ezt azért kérdezem , mert Turbopascalban a grafikus fájloknak ott kellett lenniük ahol a BGI fájl.
Amennyiben ez fontos , akkor légy szi , ezt egyszerűen és kimerítően írjátok nekem .
Valamint mindenféle zsákutcát ami szóba jöhet közöljétek, már kiraktam az elakadásjelző háromszöget.
A CS.-t dugtam D4 és D10.-re , a kártya biztosan jól van benne , nem írásvédett.
Szia, Az Adafruit_GFX könyvtárban van egy font (legalább egy, nem néztem alaposan), ami a teljes ASCII kódtáblát tartalmazza. A megoldás az lesz valószínűleg, hogy a fok jelet hexa formában teszed be: 0&F8 Egyébként itt egy elég jól összeszedett összefoglaló a lehetőségekről:
Keress olyan kijelzőt, aminek a beépített karakterkészletében van fok jel. Vagy ha nincs, csinálj egy karakterkészletet (vagy csak egy karaktert), ami akként működik, és hívd azt.
ez a furcsa a többinél. tegnap kipróbáltam úgy 15 különféle soros teminálprogramot és soros kontrollert (mint amilyen ez is).
előbb feltettem a CH341 driverét. Namármost a 15-ből 4 tökéletesen működött, az eszköz cstlakoztatásakor a rendszer rákérdez, mivel akarom összepakcsolni (melyik programmal). Ezek a programok egyébként az elindításukkor is rákérdeznek, melyik portot olvasnám, és elfogadják ezt a ch341-es virtuális com-ot. A maradék 11 viszont nem.
Egyébként az Androidnál van valami beépített alkalmazás, amivel meg tudom nézni az aktív perifériákat, mint a windowsban? van egyáltalán ilyen COM1 stb kiosztás?
Amit belinkeltél, az viszont, ha működik, pont azt tudja, amit szeretnék. Csak most estig kell várnom.
van valakinek valami KIPRÓBÁLT megoldása, amivel egy Arduinot (klónozott kínai szart, CH340-es USB interfésszel) egy Androidos tabletről lehetne USB-n keresztül vezérelni? Valami nagyon egyszerű felület kellene, néhány megjelenített számérték, néhány kapcsoló, beviteli mező. Kérlek, ne a LabViewt ajánljátok (már ha van Androidra), hanem valami egyszeűbbet . Nem baj, ha pénzbe kerül, csak ne legyen megfizethetetlen. Odáig már eljutottam, hogy az androidra fel tudtam tenni a drivert, találtam a CH341-gyel együttműködő soros port terminált. csak éppen a programok nem akarják látni az usb-n lévő áramkört.
Köszönöm , hogy ilyen kimerítően válaszoltál . Ha nem is válaszoltam , azért edzek rá .
Most még sokat puskázok és kis számokkal próbálgatok ciklusokat irkálni , hogy véremmé váljon .
A túlcsordulás nálam is megtörtént a göngyöltnél negatívvá vált , majd logikusan a következő túlcsordulásnál újból pozitívvá vált . Lassan haladok , mindig vissza kell olvasnom a Tavir elejére.
Alapvetően rengeteg olyan "bevált" módszer van, amivel ilyen és ehhez hasonló lehetetlen megoldásokat össze lehet hozni, aztán (ad abszurdum) debug helyett release fordítással meg előjön egy hiba és fingod sincs, hogy hol és mitől van.
Ha van nagyon időd, a Sololearn android (iOS?) alkalmazás C++ tesztfeladatait megnézni úgy level 2 és 7 között. Zokogok (pontot lehet kapni feladatok gyártásáért), úgyhogy olyan logikai feladatokat rittyentettek, hogy csak lestem. És a fenti hibából vagy annak valamely válfajából (operátor hatáskör-sokszorozás) minden második feladatban van. Írtam nekik párszor, a negyedik filmes screen capcure után abbahagyták a választ és csak annyit írtak, hogy "dehát senki más sem jelentette, biztos úgy jó". Valaki meg a fórumban feltette a kérdést, hogy az on-line szertifikáttal mehet-e c++ fejlesztőnek állásinterjúra. :-D
Visszatérve. Az Arduino IDE elvileg konzisztensen fordítja, legalábbis amíg a fordítót ki nem cserélik vagy nem frissítik benne.
megint egy olyan dolog, amit kerülni kellene, mert NEM az elvárt eredményt fogja adni.
Ismét C++ alapelv: a ++ operátor (incremental operator) eggyel növeli a mögötte vagy előtte lévő változó értékét, de nagyon faramuci módon.
int a = 1;
int b = a++; // b = 1, a = 2
int c = ++a; // c = 3, a = 3
Ha az operátor a változó előtt van, akkor előbb végrehajtódik a változón az érték növelése eggyel, majd felhasználásra kerül a változó a műveleti sorrend szerint. Ha a változó után van az operátor, akkor előbb felhasználja a művelethez a változót annak aktuális értékén, majd hozzáad az érintett változó értékéhez 1-et.
A forgo = forgo++; egyetlen műveletben kettő műveletet végez el, méghozzá úgy, hogy az logikailag kicsit önmagával mond ellent, pontosabban ugyanarra a változóra egyetlen műveleten belül két egymástól független műveletet végez el. A nehézség az a dologban, hogy ahány fordító, annyi féle lehetséges kimenete van ennek, emiatt c++-ban ez kifejezetten ellenjavallt eljárás (az Arduino alighanem következetesen fordítja, de ettől még nem igazolja a logika jóságát).
Talán könnyebb megérteni ezzel a példával:
int a = 1;
int b = 0;
int b = b - a--; // Mi lesz az eredmény? nagy valószínűséggel változó tulcsordulás, mert 0 - 1 sima int esetén nem -1 (mínusz 1), hanem 32766 lesz.
Igazából az eddig általam látott arduinós oktatási anyagok zöme sajnos nem éritett jól két alapvető fontosságú kérdéskört, a változó-érvényességet és a függvényeket. A függvények kezelésével is van némi következetlenséged, de legalább vannak, a változókkal van gond. Előbb nézzük a kérdéseidet:
> Ha a void setup elött valamit magadok ugye az globális?
Nem csak az a lényeg, hogy HOL, hanem hogy hogyan. Minden változó globális, amit függvényen KÍVÜL deklarálsz (vagyis nincs benne sem a void setup()-ban, sem a void main()-ben, sem más hasonlóan elnevezett függvényben.
Ezen kívül alap esetben lokálisnak tekintendő minden változó, amely bármely okból olyan szakaszon belül van, amelyet kapcsos zárójelek zárnak közre, az érvényessége pedig (persze kivételekkel) a kapcsos zárójelen belül fog tartani.
> Ha oda figyelek és minden globális, abból nem lehet nagy baj , csak ne használjam két alprogramban ugyanazt?
Ha valami globális, akkor a nevéből adódóan az összes alprogramban (nevezzük inkább függvénynek) érvényes lesz, mi több, az értékét is hozza magával és -- hacsak máshogy külön nem jelölöd -- az értéket meg is tudod változtatni úgy, hogy a teljes programon belül mindenütt az új érték lesz érvényes.
Mivel nem megy a deklarálás, nézzük a kódban lévő bajokat.
Először, a változó deklarálásának (és egyben definiálásának) formája: int valtozonev = 0;
ahol
int -- a változó típusa (lehet unsigned int, byte, const char, stb.)
valtozonev -- a változó neve, amellyel hivatkozunk rá
= 0 -- a változónak adott első (kiinduló) érték, vagyis a változó definiálása. A definíció elvileg elmaradhat, de több okból kifolyólag praktikus a deklaráláskor megtenni -- ebbe nem megyek bele külön.
; -- az elemi kódsort lezáró karakter.
Namost, nálad az a helyzet, hogy a változó MINDEN előfordulásakor kiteszed a változó elé az int jelzést, ezért nem értéket adsz (hozzárendelsz, definiálsz stb.), hanem új változót deklarálsz egy új értékkel. Az előző levelemben írtam, hogy erre (elvben, C++11 után) van mód, de rengeteg okból kerülendő. Ez egy potenciális hibaforrás runtime-errorokhoz, amiket nyilván a legnehezebb megfejteni. Erről mindenképp szokj le! Bár nem vagyok mérvadó, de még nem találkoztam olyan programozási nyelvvel, ami ezt szükségessé tette volna, és nem igazán tudok elképzelni olyan magyarázatot, ami indokolná ezt.
> Jó esetben a göngyölt változó is biztonsággal elégnek kellene lennie ,mert max 20 mérés összege is 20 x 1,023 Kbyte = még csak 20 Kbyte.
Ezzel itt van némi gond. Egyrészt, a Kbyte memóriaméret, az 1023 (ne vesszőzz, mert rettentően zavaró és egyenes út sok-sok különböző hibához) a beolvasható maximális érték (ez hardverspecifikus). 20 × 1023 = 20460, ami a változó által felvehető maximális elvárt érték, az int típusú változó pedig 32767. Ezzel tehát nincs gond.
A változó valóban foglal valamennyi memóriát, de ez nem az értéktől függ, hanem a változó típusától és az architektúrától.
> int forgo = 0 ; ez ugye értékadás , és a programban megváltoztathatom?
Ez deklaráció és definíció, vagyis létrehozás és értékadás egyszerre.
> int forgo = forgo * 5;
> int forgo = forgo++;
> int forgo = x;
Ha kihagyod előlük az int-et, akkor mind megfelelő. a forgo = forgo++; megfelel a forgo++;-nak.
Ha az int előtte van, akkor deklaráció lesz, és ha abban a szakaszban még nem volt deklarálva forgo nevű változó, akkor létre fog hozni (nested variable). Ez mindenáron kerülendő!
> int forgo (); ez mi ? mikor kell ez két zárójel ?
Ez egy függvény-deklaráció, definíció nélkül.
void setup() {}
void loop() {}
int forgo() {}
Ezek mind függvénydefiníciók, logika alapján:
void/int -- a függvény által visszaadott változó típusa (a void ún 'üres' változó, sem memóriafoglalása, sem felvehető értéke nincs),
setup / loop / forgo -- a függvény elnevezése, amellyel hivatkozunk rá (mint a változóra),
() -- a függvény paramétereinek helye, amelyet a hívásnál adunk át,
{} -- a függvény teste, lényegében utasítások sorozata.
A paraméterek helye lehet üres, illetve a test is lehet üres. A
void setup()
{ int x = 0; }
void loop() {}
egy érvényes, leforduló, bár alapvetően haszontalan Arduino kód.
Mint írtam a 60 napos arduino tanfolyam felénél járok .
A tanfolyamon még nem említettük a globális és lokális változókat.
Sajnos a turbo csak hasonló az arduinohoz.
Turboban a globális változókat a programfejben deklaráltuk
a lokálisakat pedig az procedurákban „ alprogramokban " .
Valójában kicsit előreszaladtam : valaki egy S O S ledes programot nem lefutó formában , hanem procedurásan oldott meg és ezt koppinthattam rosszul.
Program hossz 32 Kbyte lehet , csak gyakorlásképpen próbáltam rövidíteni.
Az byte mehet 255-ig , ciklusokra feltétlen elég kellene lennie, de nem fordította le.
Ide azért int.- et választottam.
Jó esetben a göngyölt változó is biztonsággal elégnek kellene lennie ,mert max 20 mérés összege is 20 x 1,023 Kbyte = még csak 20 Kbyte . Persze csak akkor ha mindig jól nullázom a változót. De itt már az NTK ellenállása 0 ohm lenne. Ha pákával melegítettem az NTK-t akkor ment fel 900 ig . Szobahőmérsékleten 400-450 volt.
Elfogadom, praktikusabb long.- változót használni . Csak a logikám szerint arra gondolta ez még belefér.
Az átlagnak turboból maradt szokás , ott az osztás eredménye „ még a 10/2 „ is csak real lehet , ami megfelel a float.-nak. Attól tartottam , hogy az átlag-ot nem fogja lefordítani int.-ben.
Mint írtam , ez csak edzés a feladat megoldásához, azért írattam ki a ciklus minden lépésénél az átlagot, hogy lássam a lépéseket. Én is arra gondoltam , hogy egyszer végzem el az osztást az utolsó ciklusnál és a göngyölteket osztom a ciklusok számával . Számtanilag értem ,de programot rosszul fogalmaztam .
Most még alaposan hozzá olvasok és számítok rátok, de szeretnék majd pontosabban kérdezni .
Csak még annyit , csodáltad , hogy lefordította a programot. NEM FORDÍTOTTA LE !! Nagyon sokadikra fordította le. És ,hogy szintaktikailag jó legyen mindig beleváltoztattam és logikailag vágtam agyon.
Légy szí , most csak erre válaszolj !
- Ha a void setup elött valamit magadok ugye az globális ?
- Ha oda figyelek és minden globális, abból nem lehet nagy baj , csak ne használjam két alprogramban ugyanazt ?
- Még bajban vagyok a deklarációkkal .
int forgo = 0 ; ez ugye értékadás , és a programban megváltoztathatom ?
int forgo = forgo * 5 ; int forgo = forgo++ ; int forgo = x ;
int forgo () ; ez mi ? mikor kell ez két zárójel ?
Bocs , hogy ennyire alapdolgokat kérdezek , én még az elektroncsővel kezdtem 1971-ben és még volt mágneses erősítő is abban a korban!
kicsit utánanolvastam, maga a chip 3,3 voltos, a panelon van egy stab IC, ami a tápfeszt leviszi 3,3-ra. ettől függetlenül, a külső tápfesz nélkül működik rosszul. írtama forgalmazónak, kíváncsi vagyok, mit lépnek. mindenki csak jót írt a termékről.
Kódmegosztáshoz javaslom valamelyik kódmegosztó oldalra feltenni a forrást (copy + paste) és csak a linket mellékelni. Pl. codeshare.
Rengeteg logikai és szintaktikai bukfenc van a kódodban, sorolom.
int forgo () ; // globalis valtozo , hanyszor fordult korbe a teljes forciklus
Nem. Ez egy függvénydeklaráció. Helyesen:
int forgo = 0;
A zárójeles megoldás a függvény paramétereit tartalmazza, ez esetben ez egy int típusú változót visszaadó függvény deklarációja. Az IDE biztos szólt miatta.
A deklaráció során egyből definiáltad is a változót kezdő értékre. Ezt javasolt minden változómegadásnál megtenni!
A for ciklus anomáliájára önállóan rájöttél, ez kafa.
void megresz() függvényben rossz az átlagolás logikája. Mint régen matekból: (1) összeadjuk az értékeket (2) az összeget elosztjuk az egyedi értékek darabszámával. Vagyis a for ciklus körbemegy az elvárt számú alkalommal, majd a szamgongyolve változó értékét elosztod az iterálások számával (ami 9 lesz, ha a for ciklus indexét ciklus < 10 limittel adod meg).
Itt van több további bukfenc is. Egyrészt kellően nagy szam valtozó esetén vagy kellően nagy számú iterációnál simán előfordulhat, hogy a szamgongyolve valtozó értéke túlfut a maximumán, ami 32737. Ennek elkerülésére az a mód, hogy az int típusú változó helyett jóval nagyobbat választunk, mondjuk egy long-ot vagy unsigned long-ot (előbbi 2, utóbbi 4 milliárdig nyerő, cserébe többet foglal a memóriából) -- a kettő között azért van átjárás.
A függvényen belül újra definiáltad a szam és a forgo változókat, ez elég rossz ötlet. Simán szedd ki előlük az int utasítást.
Serial.println (" ") ; felesleges, elég a Serial.println();
A delay(2000); most még jó, de elég gyorsan el kellene felejteni.
Később: előző mérés + új mérés / aktuális ciklus = átlag ez így teljesen rossz, ez nem átlag és így nem is lehet átlagot számolni, mert az utolsó mérés súlya mindig exponenciálisan nagyobb lesz, mint az összes korábbi mérésé.
Az atlag is lehet nyugodtan int. Felesleges a tizedesekkel bajlódni (pontosítani persze lehet, de kérdés, hogy érdemes-e ezen a szinten).
A felvetésed, hogy a szamgongyolve változó miért nem nullázódik egy kicsit hosszabb leírást szorgalmaz.
Nyitásra az, hogy függvényeket (procedúrákat) használsz, dícséretes, viszont egy nagyon fontos dolgot figyelmen kívül hagysz, ez pedig a változók hatóköre. A program elején deklarálod a szamgongyolve változót int típusúként (illetve valójában nem, mert egy függvényt deklarálsz csak, csodálom, hogy nem kajabál az IDE, hogy rossz az egész). Ez globális változó lesz (lenne). Ezt követően mind a nullazo() mind a megresz() függvényben újra deklarálod őket (a változó neve elé kiteszed a változó típusát jelző int utasítást). Ezt beágyazott változókezelésnek hívják, és bár logikailag/szintaktikailag működik, programozástechnikailag a taposóakna megfelelője, ezért kerülendő.
A dolog úgy javítható egyszerűen, hogy a fentieket is követve csak és kizárólag a program elején (vagy a változó első előfordulásakor) használod a változódeklarálást jelző utasítást (gyakorlatilag a változó típusának jelölését).
Végül. Az egész program logikája sok ponton hibás. A függvények egymás után futtatásával (különösen az összehasonlito() fügvény esetén) biztosan nem az elvárt eredményt fogod kapni (ez a nevesített ugyanis minden futtatásakor PONTOSAN ugyanazt az eredményt fogja adni, és nem csak azért, mert a vizsgálat hibás -- == helyett = van --, hanem azért is, mert mindig ugyanazzal a szam változó-értékkel fog elindulni.
30 mp-es mintavételeknél azt javaslom, hogy 2 mp-es mintavételezést használj 14 mintavételt átlagolj a két-két szélsőérték (maximum és minimum) eldobásával és ezt rögzítsd. Ezzel jó szerencsével minden külső tényezőt ki tudsz szűrni.