Fórum témák
- • SONY TA-F 590ES MOSFET végfok átalakítása
- • TV hiba, mi a megoldás?
- • Li-Po - Li-ion akkumulátor és töltője
- • Suzuki Swift elektronika
- • Számítógép hiba, de mi a probléma?
- • Villanyszerelés
- • Kávéfőzőgép hiba
- • LCD TV probléma
- • Erősítő mindig és mindig
- • Alkony és pirkadat kapcsoló
- • Kombikazán működési hiba
- • DC motor/lámpa PWM szabályzása
- • VF3 - 6 végerősítő
- • Erősítő építése elejétől a végéig
- • Felajánlás, azaz ingyen elvihető
- • Internetes rádióvevő
- • IR távirányító
- • SMD forrasztás profin
- • Elfogadnám, ha ingyen elvihető
- • Gázkazán vezérlő hibák
- • Indukciós főzőlap javítása
- • Autóelektronika
- • Rádiós adó-vevő modulok
- • LED kijelzős digitális óra
- • Arduino
- • Transzformátor készítés, méretezés
- • Nullátmenet kapcsoló
- • Vásárlás, hol kapható?
- • Érdekességek
- • Akkumulátoros fúró
- • Rádióamatőrök topikja
- • Frekvenciaváltó 1-ről 3 fázisra
- • ZC-18 kazán
- • VF2 végerősítő
- • Hűtőgép kompresszor
- • Leválasztó transzformátor
- • Elektromos távirányítós kapunyitó
- • Kapcsolóüzemű tápegység
- • Westen 240 Fi gázkazán hiba
- • Hangsugárzó építés, javítás - miértek, hogyanok
- • Tápegység
- • Kazettás magnó (deck) javítása
- • Búvár lámpa elektronika készítés
- • LED-es világítás
- • Tápegységgel kapcsolatos kérdések
- • China LCD Kijelző
- • Eaton E5 650i USB fogyasztás mérés probléma
- • Elektronikus szulfátoldó (Akku aktivátor)
- • Inverteres hegesztőtrafó
- • Vicces - mókás történetek
- • Konyhai szagelszívó-páraérzékelés
- • Klíma szervizelés, javítás
- • 3D nyomtatás
- • Gyors hőmérséklet mérés tapintó érzékelővel ellátott műszerrel
- • Rádió áthangolása, OIRT - CCIR konverter
» Több friss téma
|
A klónok CH340 Soros-USB illesztőjének drivere ( Letöltés)
Mekkora az UART baud rate, amit meg kell valósítani? Létezik egy AltSoftSerial lib is, ami működik Atmega328-cal, és a szoftveres UART-tal ellentétben nem blokkoló módban működik mind a TX, mind az RX: https://www.arduino.cc/reference/en/libraries/altsoftserial/ Viszont lefoglal egy timert, amit lehet, hogy használsz az impulzusok kiadásához... Szóval meg kell szakérteni.
Ja, és az egyetlen UART sem szabadon használható az Arduino UNO-n, mert erről megy a programozás és debuggolás! Ezért is ésszerű UART-os feladatot több UART-os csippel csinálni.
Én is azt javasolnám, hogy vegyél egy olyan csipet és boardot, amin eleve van több serial, minek szivassa magát az ember? Az STM32-őkhöz például vannak a Nucleo boardok (Hestore-on is kapható), ilyennel van tapasztalatom és csupa jó. Ez is programozható Arduinoként, kis szerencsével az eredeti program életre kelthető ezzel is.
Vagy ha 8 bites AVR-en akarsz maradni, akkor ott van az Arduino mega2560, ebben egy nagyobb ATMega van, amin már van több hardveres UART. A hozzászólás módosítva: Nov 21, 2023
Alakul a kód, de így még nem azonos időnként írja a displayre az adatokat.
Hogyan kellene megváltoztatni az azonos kiíráshoz?
// 5 "independant" timed events.
const long eventTime_1 = 1000; //Soros portra kiírja az akku paramétereket.
const long eventTime_2 = eventTime_1 +2000; //Soros portra LoRa packet és displayre.
const long eventTime_3 = eventTime_2 +1000; //Soros portra displayinfo kiírása.
const long eventTime_4 = eventTime_3 +2000; //Displayre kordináták kiírása.
const long eventTime_5 = eventTime_4 +2000; //Displayre idő kiírása.
//When did they start the race?.
unsigned long previousTime_1 = 0;
unsigned long previousTime_2 = 0;
unsigned long previousTime_3 = 0;
unsigned long previousTime_4 = 0;
unsigned long previousTime_5 = 0;
Van ez a sor a kódodban, ez nagyon nem jó, az aktuális idővel plusz 10 milliszekundummal növeled a startpontot (ismétlődő rossz minta a kódban, egyet másoltam ide):
start1Millis += millis() + 10;
Helyette egy periódusidővel kell növelni a startpontot:
const long periodMillis=4000;
...
start1Millis += periodMillis;
Másik probléma, hogy a millis() átfordul néhány óránként, vagy naponként (nézz utána) a számábrázolás végessége miatt. Ezért a kisebb-nagyobb kérdést így kell eldönteni:
if (millis() > start1Millis)
helyett:
if (( (signed long)(millis()-start1Millis))>0)
Magyarázat: a különbségképzés akkor is jól működik, ha éppen átfordultunk a két érték között. (Ameddig a különbségek kisebbek mint az átfordulás periódusának a fele.) (Kukacoskodóknak megjegyzés: a C szabvány az előjeles átfordulás módját nem specifikálja, ha a szabvány szerint korrektek akarunk lenni, akkor csak unsigned esetben számolhatunk azzal, hogy az átfordulás így működik. De még nem láttam olyan platformot, ahol nem így működött volna.) A hozzászólás módosítva: Nov 21, 2023
Köszönöm hogy foglalkoztál a kérdéssel, a fenti megoldásomban valami hasonlót találtam ki.
Ha jól gondolom a különböző periódusidők alkalmazását.
Az adott időzítéssel lefutnak a kódrészek periódikusan, a gond a kijelzőn ábrázolással van, nem meghatározott időnként és sorrendben jelennek meg az egyes programrészek.
A fentebbi hozzászólásodba tett kódodban találtam ezeket a hibákat, amik valósak és pont az általad leírt hibajelenséget okozzák, nevezetesen, hogy a loop ütemei össze-vissza történnek.
```cpp
#include <LoRa.h>
#include <TinyGPS++.h>
#include "boards.h"
TinyGPSPlus gps;
#if !defined(LILYGO_TBeamS3_SUPREME_V3_0) && !defined(LILYGO_TBeam_V1_X)
#error "The sketch is only suitable for boards carrying AXP192 or AXP2101 chips!"
#endif
uint32_t start1Millis; //Soros portra kiírja az akku adatait.
uint32_t start2Millis; //Soros portra és displayre kiírja LoRa packetet
uint32_t start3Millis; //Soros portra kiírja displayinfot.
uint32_t start4Millis; //Displayre kiírja GPS kordinátákat.
uint32_t start5Millis; //Displayre kiírja GPS idő és magasság adatokat.
void setup()
{
initBoard();
delay(1500);
Serial.println("LoRa Receiver");
LoRa.setPins(RADIO_CS_PIN, RADIO_RST_PIN, RADIO_DIO0_PIN);
if (!LoRa.begin(LoRa_frequency)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. "));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop()
{
const long periodMillis=4000;
if (( (signed long)(millis()-start1Millis))>0)
{
Serial.print("isCharging:"); Serial.println(PMU->isCharging() ? "YES" : "NO");
Serial.print("isDischarge:"); Serial.println(PMU->isDischarge() ? "YES" : "NO");
Serial.print("isVbusIn:"); Serial.println(PMU->isVbusIn() ? "YES" : "NO");
Serial.print("getBattVoltage:"); Serial.print(PMU->getBattVoltage()); Serial.println("mV");
Serial.print("getVbusVoltage:"); Serial.print(PMU->getVbusVoltage()); Serial.println("mV");
Serial.print("getSystemVoltage:"); Serial.print(PMU->getSystemVoltage()); Serial.println("mV");
// The battery percentage may be inaccurate at first use, the PMU will automatically
// learn the battery curve and will automatically calibrate the battery percentage
// after a charge and discharge cycle
if (PMU->isBatteryConnect())
{
Serial.print("getBatteryPercent:"); Serial.print(PMU->getBatteryPercent()); Serial.println("%");
}
Serial.println();
start1Millis += periodMillis;
}
if (pmuInterrupt)
{
pmuInterrupt = false;
// Get PMU Interrupt Status Register
uint32_t status = PMU->getIrqStatus();
Serial.print("STATUS => HEX:");
Serial.print(status, HEX);
Serial.print(" BIN:");
Serial.println(status, BIN);
if (PMU->isVbusInsertIrq()) {
Serial.println("isVbusInsert");
}
if (PMU->isVbusRemoveIrq()) {
Serial.println("isVbusRemove");
}
if (PMU->isBatInsertIrq()) {
Serial.println("isBatInsert");
}
if (PMU->isBatRemoveIrq()) {
Serial.println("isBatRemove");
}
if (PMU->isPekeyShortPressIrq()) {
Serial.println("isPekeyShortPress");
}
if (PMU->isPekeyLongPressIrq()) {
Serial.println("isPekeyLongPress");
}
if (PMU->isBatChagerDoneIrq()) {
Serial.println("isBatChagerDone");
}
if (PMU->isBatChagerStartIrq()) {
Serial.println("isBatChagerStart");
}
// Clear PMU Interrupt Status Register
PMU->clearIrqStatus();
}
if (( (signed long)(millis()-start2Millis))>0)
{
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize)
{
// received a packet
Serial.print("Received packet ");
String recv = "";
// read packet
while (LoRa.available())
{
recv += (char)LoRa.read();
}
Serial.println(recv);
// print RSSI of packet
Serial.print("' with RSSI: ");
Serial.println(LoRa.packetRssi());
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
char buf[256];
u8g2->drawStr(0, 12, "Received OK!");
u8g2->setCursor(0, 25);
u8g2->print(PMU->getBattVoltage()); //u8g2->drawStr(0, 26, recv.c_str());
u8g2->println(" mV");
snprintf(buf, sizeof(buf), "RSSI:%i", LoRa.packetRssi());
u8g2->drawStr(0, 40, buf);
snprintf(buf, sizeof(buf), "SNR:%.1f", LoRa.packetSnr());
u8g2->drawStr(0, 56, buf);
while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start2Millis += periodMillis;
}
}
#endif
}
// This sketch displays information every time a new sentence is correctly encoded.
while (Serial1.available() > 0)
if (gps.encode(Serial1.read()))
if (( (signed long)(millis()-start3Millis))>0)
{
displayInfo();
start3Millis += periodMillis;
}
if (( (signed long)(millis()-start4Millis))>0)
{
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
do
{
u8g2->setCursor(0, 16);
u8g2->println( "Location.lat:");
u8g2->setCursor(0, 32);
u8g2->print(gps.location.lat(), 6);
u8g2->println(" deg");
u8g2->setCursor(0, 48);
u8g2->println( "Location.lng:");
u8g2->setCursor(0, 64);
u8g2->print(gps.location.lng(), 6);
u8g2->println(" deg");
} while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start4Millis += periodMillis;
}
#endif
}
if (( (signed long)(millis()-start5Millis))>0)
{
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
do
{
u8g2->setCursor(0, 16);
u8g2->print( "Hour: ");
u8g2->println(gps.time.hour());
u8g2->setCursor(0, 32);
u8g2->print("minute: ");
u8g2->println(gps.time.minute());
u8g2->setCursor(0, 48);
u8g2->print( "second: ");
u8g2->println(gps.time.second());
u8g2->setCursor(0, 64);
u8g2->print("altitude: ");
u8g2->println(gps.altitude.meters());
}
while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start5Millis += periodMillis;
}
#endif
}
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while (true);
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
} else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
} else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.print(gps.time.centisecond());
} else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
```
Displayen 2-es fut, 5-ös után 4-es bevillan, (5,4 3x), soros porton 1-es és 3-as fut, majd 2-es.
Helló! Igazából semmi, de ha szoftveresen megoldható, az az igazi. Minél kevesebb alkatrész, annál jobb.
Úgy kell elképzelni, hogy mindkét tengelyen csak az egyik irány a "munkamenet", a másik irányban pedig minél gyorsabb visszaállítást kell megoldani.
Nincs megkötés a baud ratere. A chip nem Arduino boardon van, hanem direkt a feladatra tervezett pcb-n.
Valószínűleg tényleg egy másik chip lesz a végső megoldás.
```cpp
#include <LoRa.h>
#include <TinyGPS++.h>
#include "boards.h"
TinyGPSPlus gps;
#if !defined(LILYGO_TBeamS3_SUPREME_V3_0) && !defined(LILYGO_TBeam_V1_X)
#error "The sketch is only suitable for boards carrying AXP192 or AXP2101 chips!"
#endif
uint32_t start1Millis; //Soros portra kiírja az akku adatait.
uint32_t start2Millis; //Soros portra és displayre kiírja LoRa packetet
uint32_t start3Millis; //Soros portra kiírja displayinfot, displayre kiírja GPS kordinátákat.
uint32_t start4Millis; //Displayre kiírja GPS idő és magasság adatokat.
void setup()
{
initBoard();
delay(1500);
Serial.println("LoRa Receiver");
LoRa.setPins(RADIO_CS_PIN, RADIO_RST_PIN, RADIO_DIO0_PIN);
if (!LoRa.begin(LoRa_frequency)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. "));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop()
{
const long periodMillis=4000;
if (( (signed long)(millis()-start1Millis))>0)
{
Serial.print("isCharging:"); Serial.println(PMU->isCharging() ? "YES" : "NO");
Serial.print("isDischarge:"); Serial.println(PMU->isDischarge() ? "YES" : "NO");
Serial.print("isVbusIn:"); Serial.println(PMU->isVbusIn() ? "YES" : "NO");
Serial.print("getBattVoltage:"); Serial.print(PMU->getBattVoltage()); Serial.println("mV");
Serial.print("getVbusVoltage:"); Serial.print(PMU->getVbusVoltage()); Serial.println("mV");
Serial.print("getSystemVoltage:"); Serial.print(PMU->getSystemVoltage()); Serial.println("mV");
// The battery percentage may be inaccurate at first use, the PMU will automatically
// learn the battery curve and will automatically calibrate the battery percentage
// after a charge and discharge cycle
if (PMU->isBatteryConnect())
{
Serial.print("getBatteryPercent:"); Serial.print(PMU->getBatteryPercent()); Serial.println("%");
}
Serial.println();
start1Millis += periodMillis;
}
if (pmuInterrupt)
{
pmuInterrupt = false;
// Get PMU Interrupt Status Register
uint32_t status = PMU->getIrqStatus();
Serial.print("STATUS => HEX:");
Serial.print(status, HEX);
Serial.print(" BIN:");
Serial.println(status, BIN);
if (PMU->isVbusInsertIrq()) {
Serial.println("isVbusInsert");
}
if (PMU->isVbusRemoveIrq()) {
Serial.println("isVbusRemove");
}
if (PMU->isBatInsertIrq()) {
Serial.println("isBatInsert");
}
if (PMU->isBatRemoveIrq()) {
Serial.println("isBatRemove");
}
if (PMU->isPekeyShortPressIrq()) {
Serial.println("isPekeyShortPress");
}
if (PMU->isPekeyLongPressIrq()) {
Serial.println("isPekeyLongPress");
}
if (PMU->isBatChagerDoneIrq()) {
Serial.println("isBatChagerDone");
}
if (PMU->isBatChagerStartIrq()) {
Serial.println("isBatChagerStart");
}
// Clear PMU Interrupt Status Register
PMU->clearIrqStatus();
}
if (( (signed long)(millis()-start2Millis))>0)
{
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize)
{
// received a packet
Serial.print("Received packet ");
String recv = "";
// read packet
while (LoRa.available())
{
recv += (char)LoRa.read();
}
Serial.println(recv);
// print RSSI of packet
Serial.print("' with RSSI: ");
Serial.println(LoRa.packetRssi());
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
char buf[256];
u8g2->drawStr(0, 12, "Received OK!");
u8g2->setCursor(0, 25);
u8g2->print(PMU->getBattVoltage()); //u8g2->drawStr(0, 26, recv.c_str());
u8g2->println(" mV");
snprintf(buf, sizeof(buf), "RSSI:%i", LoRa.packetRssi());
u8g2->drawStr(0, 40, buf);
snprintf(buf, sizeof(buf), "SNR:%.1f", LoRa.packetSnr());
u8g2->drawStr(0, 56, buf);
while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start2Millis += periodMillis;
}
}
#endif
}
// This sketch displays information every time a new sentence is correctly encoded.
while (Serial1.available() > 0)
if (gps.encode(Serial1.read()))
if (( (signed long)(millis()-start3Millis))>0)
{
displayInfo();
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
do
{
u8g2->setCursor(0, 16);
u8g2->println( "Location.lat:");
u8g2->setCursor(0, 32);
u8g2->print(gps.location.lat(), 6);
u8g2->println(" deg");
u8g2->setCursor(0, 48);
u8g2->println( "Location.lng:");
u8g2->setCursor(0, 64);
u8g2->print(gps.location.lng(), 6);
u8g2->println(" deg");
} while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
}
#endif
start3Millis += periodMillis +4000;
}
if (( (signed long)(millis()-start4Millis))>0)
{
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
do
{
u8g2->setCursor(0, 16);
u8g2->print( "Hour: ");
u8g2->println(gps.time.hour());
u8g2->setCursor(0, 32);
u8g2->print("minute: ");
u8g2->println(gps.time.minute());
u8g2->setCursor(0, 48);
u8g2->print( "second: ");
u8g2->println(gps.time.second());
u8g2->setCursor(0, 64);
u8g2->print("altitude: ");
u8g2->println(gps.altitude.meters());
}
while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start4Millis += periodMillis;
}
#endif
}
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while (true);
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
} else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
} else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.print(gps.time.centisecond());
} else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
```
A displayen 8 sec-ént kiírja a GPS időt, a GPS kordináták és a LoRa packet közben együtt, vagy egyedül.
Ami eszembe jutott, ha már minden összevissza fut le, lehet a processzornak nincs ideje/nem kapja időben az adatokat. A másik, annyi serial.print utasítás van, de azt nem látom a baudrate mekkora. Lehet nincs is ideje mindent elrendezni.
A startXMillis változók kezdeti értéke nincs beállítva, 0 vagy memóriaszemét lesz a kezdeti értékük. Ez zavarja össze. Ezekbe a perióduson belüli fázist kell beírni, például 1000, 2000, 3000, stb.
uint32_t start1Millis = 5000; //Soros portra kiírja az akku adatait.
uint32_t start2Millis = 4000; //Soros portra és displayre kiírja LoRa packetet.
uint32_t start3Millis = 3000; //Soros portra kiírja displayinfot.
uint32_t start4Millis = 2000; //Displayre kiírja GPS kordinátákat.
uint32_t start5Millis = 1000; //Displayre kiírja GPS idő és magasság adatokat.
Hogyan írjam 2>5>4>2 sorrendhez?
Displayen most 4 secenként változik, 2>5>4>5>4>5>4>2 sorrendben.
Baudrate: 115200
```cpp
#include <LoRa.h>
#include <TinyGPS++.h>
#include "boards.h"
TinyGPSPlus gps;
#if !defined(LILYGO_TBeamS3_SUPREME_V3_0) && !defined(LILYGO_TBeam_V1_X)
#error "The sketch is only suitable for boards carrying AXP192 or AXP2101 chips!"
#endif
uint32_t start1Millis = 5000; //Soros portra kiírja az akku adatait.
uint32_t start2Millis = 4000; //Soros portra és displayre kiírja LoRa packetet.
uint32_t start3Millis = 3000; //Soros portra kiírja displayinfot.
uint32_t start4Millis = 2000; //Displayre kiírja GPS kordinátákat.
uint32_t start5Millis = 1000; //Displayre kiírja GPS idő és magasság adatokat.
void setup()
{
initBoard();
delay(1500);
Serial.println("LoRa Receiver");
LoRa.setPins(RADIO_CS_PIN, RADIO_RST_PIN, RADIO_DIO0_PIN);
if (!LoRa.begin(LoRa_frequency)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. "));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop()
{
const long periodMillis=4000;
if (( (signed long)(millis()-start1Millis))>0)
{
Serial.print("isCharging:"); Serial.println(PMU->isCharging() ? "YES" : "NO");
Serial.print("isDischarge:"); Serial.println(PMU->isDischarge() ? "YES" : "NO");
Serial.print("isVbusIn:"); Serial.println(PMU->isVbusIn() ? "YES" : "NO");
Serial.print("getBattVoltage:"); Serial.print(PMU->getBattVoltage()); Serial.println("mV");
Serial.print("getVbusVoltage:"); Serial.print(PMU->getVbusVoltage()); Serial.println("mV");
Serial.print("getSystemVoltage:"); Serial.print(PMU->getSystemVoltage()); Serial.println("mV");
// The battery percentage may be inaccurate at first use, the PMU will automatically
// learn the battery curve and will automatically calibrate the battery percentage
// after a charge and discharge cycle
if (PMU->isBatteryConnect())
{
Serial.print("getBatteryPercent:"); Serial.print(PMU->getBatteryPercent()); Serial.println("%");
}
Serial.println();
start1Millis += periodMillis;
}
if (pmuInterrupt)
{
pmuInterrupt = false;
// Get PMU Interrupt Status Register
uint32_t status = PMU->getIrqStatus();
Serial.print("STATUS => HEX:");
Serial.print(status, HEX);
Serial.print(" BIN:");
Serial.println(status, BIN);
if (PMU->isVbusInsertIrq()) {
Serial.println("isVbusInsert");
}
if (PMU->isVbusRemoveIrq()) {
Serial.println("isVbusRemove");
}
if (PMU->isBatInsertIrq()) {
Serial.println("isBatInsert");
}
if (PMU->isBatRemoveIrq()) {
Serial.println("isBatRemove");
}
if (PMU->isPekeyShortPressIrq()) {
Serial.println("isPekeyShortPress");
}
if (PMU->isPekeyLongPressIrq()) {
Serial.println("isPekeyLongPress");
}
if (PMU->isBatChagerDoneIrq()) {
Serial.println("isBatChagerDone");
}
if (PMU->isBatChagerStartIrq()) {
Serial.println("isBatChagerStart");
}
// Clear PMU Interrupt Status Register
PMU->clearIrqStatus();
}
if (( (signed long)(millis()-start2Millis))>0)
{
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize)
{
// received a packet
Serial.print("Received packet ");
String recv = "";
// read packet
while (LoRa.available())
{
recv += (char)LoRa.read();
}
Serial.println(recv);
// print RSSI of packet
Serial.print("' with RSSI: ");
Serial.println(LoRa.packetRssi());
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
char buf[256];
u8g2->drawStr(0, 12, "Received OK!");
u8g2->setCursor(0, 25);
u8g2->print(PMU->getBattVoltage()); //u8g2->drawStr(0, 26, recv.c_str());
u8g2->println(" mV");
snprintf(buf, sizeof(buf), "RSSI:%i", LoRa.packetRssi());
u8g2->drawStr(0, 40, buf);
snprintf(buf, sizeof(buf), "SNR:%.1f", LoRa.packetSnr());
u8g2->drawStr(0, 56, buf);
while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start2Millis += periodMillis;
}
}
#endif
}
// This sketch displays information every time a new sentence is correctly encoded.
while (Serial1.available() > 0)
if (gps.encode(Serial1.read()))
if (( (signed long)(millis()-start3Millis))>0)
{
displayInfo();
start3Millis += periodMillis;
}
if (( (signed long)(millis()-start4Millis))>0)
{
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
do
{
u8g2->setCursor(0, 16);
u8g2->println( "Location.lat:");
u8g2->setCursor(0, 32);
u8g2->print(gps.location.lat(), 6);
u8g2->println(" deg");
u8g2->setCursor(0, 48);
u8g2->println( "Location.lng:");
u8g2->setCursor(0, 64);
u8g2->print(gps.location.lng(), 6);
u8g2->println(" deg");
} while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
}
start4Millis += periodMillis;
#endif
}
if (( (signed long)(millis()-start5Millis))>0)
{
#ifdef HAS_DISPLAY
if (u8g2)
{
u8g2->clearBuffer();
do
{
u8g2->setCursor(0, 16);
u8g2->print( "Hour: ");
u8g2->println(gps.time.hour());
u8g2->setCursor(0, 32);
u8g2->print("minute: ");
u8g2->println(gps.time.minute());
u8g2->setCursor(0, 48);
u8g2->print( "second: ");
u8g2->println(gps.time.second());
u8g2->setCursor(0, 64);
u8g2->print("altitude: ");
u8g2->println(gps.altitude.meters());
}
while ( u8g2->nextPage() );
u8g2->sendBuffer();
u8g2->setFont(u8g2_font_fur11_tf);
start5Millis += periodMillis;
}
#endif
}
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while (true);
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
} else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
} else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.print(gps.time.centisecond());
} else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
```
A hozzászólás módosítva: Nov 22, 2023
A periodMillis egy periódus hossza milliszekundumban. A startXMillis az, hogy a perióduson belül mikor indul el az adott feladat. Tehát a periodMillis-nek többnek kell lenni, mint a legnagyobb startXMillis ahhoz, hogy értelmes legyen. Ezen kívül a startXMillis-ek közötti különbségnek elégnek kell lenni arra, hogy az adott taszk lefusson, akkor fog tudni stabilan működni.
Én egyébként egy állapotgépes megoldást javasolnék arra, hogy sorban végigmenjen a program az összes állapoton, és ezt egészíteném ki azzal, hogy az állapotgépet például másodpercenként egyszer hívnám meg. Sokkal átláthatóbb lenne és nehezebb lenne elrontani. Általánosságban, ha a paramétereink között redundancia van, akkor azt el lehet rontani. A beállítási paramétereket úgy kell meghatározni, hogy azok között ne legyen redundancia, azaz egymástól függetlenül állíthatóak legyenek és minden ami az adott paramétertől függ, az automatikusan utánaálljon. A redundanciák nálad: a startXmillis értékek között valójában a különbség az ami számít, annak kellene a változónak lenni. A periodMillis pedig legnagyobb startXMillis érték plusz egy várakozás kell hogy legyen.
//Cikluson belül a futás indításának kezdete.
uint32_t start1Millis = 0; //Soros portra kiírja az akku adatait.
uint32_t start2Millis = 2000; //Soros portra és displayre kiírja LoRa packetet.
uint32_t start3Millis = 4000; //Soros portra kiírja displayinfot.
uint32_t start4Millis = 7000; //Displayre kiírja GPS kordinátákat.
uint32_t start5Millis = 9000; //Displayre kiírja GPS idő és magasság adatokat.
const long periodMillis=10000; // Egy ciklus teljes ideje.
Így viszonylag ciklikusan fut, néha ki-kimarad egy futás.
Minden LoRa packetet kiír, a GPS vétele is rendben.
Az még megfontolandó hogy szükséges-e a display mellett a soros portra írás is pl. terepen.
Az állapotgépes futtatást egy másik modulnál már néztem.
LoRaWan alkalmazásban hasonlóan érthető ismertetőt keresek, különös tekintettel a smart árammérők P1 portjának kiolvasására.
Lehet ezt is figyelembe kellene vennem adásnál:
"A harmonizált rendelet a végberendezésekben és az átjárókban alkalmazott rádiókra egyaránt 25 mW maximális adóteljesítményt enged meg. A sáv egyes részein az adási kitöltési tényező 0,1%, máshol 1% lehet. Ez a korlátozás azt jelenti, hogy egy adott frekvencián leadott 1 másodperces üzenet után 999, illetve 99 másodperc szünetet kell tartani. Az egytized másodperces üzenetcsomag esetén 99,9, illetve 9,9 másodperc adásszünet betartása kötelező! Ez a hatósági előírás fontos, mivel ez biztosítja, hogy az állandó helyre telepített berendezések egyike se uralhassa a sávot." A hozzászólás módosítva: Nov 23, 2023
(#) |
MATA hozzászólása |
Nov 27, 2023 |
|
/ |
|
|
Üdv mesterek!
A következő gondom lenne összeraktam egy kapcsolást ezt:
https://www.instructables.com/DIY-Multifunction-Energy-Meter-V20/
Feltöltöttem a Wemos D1 mini Pro-ra a kódot de csak azt írja ki hogy "Open Green Energy"
és mást semmit mi lehet itt a probléma?
Előre is köszönöm!
Itt a kód is:
#define BLYNK_PRINT Serial
#define BLYNK_MAX_READBYTES 512
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/****************************************************************************/
BlynkTimer timer;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Virtual Pins - Base
#define vPIN_VOLTAGE V0
#define vPIN_CURRENT V1
#define vPIN_POWER V2
#define vPIN_ENERGY V3
#define vPIN_CAPACITY V4
#define vPIN_TEMP V5
#define vPIN_CURRENT_GRAPH V6
#define vPIN_ENERGY_PRICE V7
#define vPIN_ENERGY_COST V8
#define vPIN_BUTTON_AUTORANGE V9
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// GPIO where the DS18B20 is connected to
const int oneWireBus = 2;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
float shuntvoltage = 0.00;
float busvoltage = 0.00;
float current_mA = 0.00;
float loadvoltage = 0.00;
float energy = 0.00, energyCost, energyPrevious, energyDifference;
float energyPrice = 5.25 ;
float power = 0.00;
float tempC=0.00;
float tempF=0.00;
float capacity=0.00;
int sendTimer, pollingTimer, priceTimer, graphTimer, autoRange, countdownResetCon, countdownResetClock, counter2, secret, stopwatchTimer;
long stopwatch;
int splitTimer1, splitTimer2, splitTimer3, splitTimer4, splitTimer5;
int sendTimer1, sendTimer2, sendTimer3, sendTimer4, sendTimer5;
unsigned long previousMillis = 0;
unsigned long interval = 100;
char auth[] = "XXXX"; // Enter Blynk auth id
char ssid[] = "XXXX"; //Enter your WIFI Name
char pass[] = "XXXX"; //Enter your WIFI Password
/****************************************************************************/
void get_sensor_data() {
// get the INA219 and DS18B20 Sensor values and throw some basic math at them
shuntvoltage = ina219. getShuntVoltage_mV();
busvoltage = ina219. getBusVoltage_V();
current_mA = ina219. getCurrent_mA();
loadvoltage = busvoltage + (shuntvoltage / 1000); // V
power = current_mA * loadvoltage ; // mW
energy = energy + (power / 1000 / 1000); //Wh
capacity = capacity + current_mA/1000;
// nothing connected? set all to 0, otherwise they float around 0.
if (loadvoltage < 1.2 )loadvoltage = 0;
if(current_mA < 2 )
{
current_mA = 0;
power = 0;
energy = 0;
capacity=0;
}
sensors.requestTemperatures(); // get temperatures
tempC = sensors.getTempCByIndex(0);
//tempF = sensors.getTempFByIndex(0);
}
// this function is for updaing the REAL TIME values and is on a timer
void display_data() {
// VOLTAGE
Blynk.virtualWrite(vPIN_VOLTAGE, String(loadvoltage, 2) + String(" V") );
display.clearDisplay();
display.setCursor(0, 10);
display.print(loadvoltage);
display.print(" V");
// CURRENT
if (current_mA > 1000 && autoRange == 1) {
Blynk.virtualWrite(vPIN_CURRENT, String((current_mA / 1000), 3) + String(" A") );
display.setCursor(0, 30);
display.print((current_mA / 1000), 2);
display.print(" A");
} else {
Blynk.virtualWrite(vPIN_CURRENT, String(current_mA, 2) + String(" mA"));
display.setCursor(0, 30);
display.print(current_mA,1);
display.print(" mA");
}
// POWER
if (power > 1000 && autoRange == 1) {
Blynk.virtualWrite(vPIN_POWER, String((power / 1000), 3) + String(" W") );
display.setCursor(0, 50);
display.print(String((power / 1000),2));
display.print(" W");
} else {
Blynk.virtualWrite(vPIN_POWER, String(power, 0) + String(" mW") );
display.setCursor(0, 50);
display.print(power,0);
display.print(" mW");
}
energyDifference = energy - energyPrevious;
// ENERGY CONSUMPTION
if (energy > 1000 && autoRange == 1) {
Blynk.virtualWrite(vPIN_ENERGY, String((energy / 1000), 3) + String(" kWh"));
display.setCursor(70,10);
display.print((energy/1000),3);
display.println(" kWh");
} else {
Blynk.virtualWrite(vPIN_ENERGY, String(energy, 3) + String(" Wh"));
display.setCursor(70,10);
display.print(energy,3);
display.println(" Wh");
}
energyPrevious = energy;
// ENERGY COST
energyCost = energyCost + ((energyPrice / 1000 / 100) * energyDifference);
if (energyCost > 9.999) {
Blynk.virtualWrite(vPIN_ENERGY_COST, String((energyCost),7));
} else {
Blynk.virtualWrite(vPIN_ENERGY_COST, String((energyCost), 7));
}
// CAPACITY
if (capacity > 1000 && autoRange == 1){
Blynk.virtualWrite(vPIN_CAPACITY, String((capacity/ 1000), 2) + String(" Ah") );
display.setCursor(70,30);
display.print((capacity/1000),2);
display.println(" Ah");
}
else{
Blynk.virtualWrite(vPIN_CAPACITY, String((capacity), 2) + String(" mAh") );
display.setCursor(70,30);
display.print(capacity,1);
display.println(" mAh");
}
// TEMPERATURE
display.setCursor(70,50);
display.print(tempC);
display.println(" C");
//display.println(" F");
Blynk.virtualWrite(vPIN_TEMP, String(tempC, 2) + String(" ºC") );
//Blynk.virtualWrite(vPIN_TEMP, String(tempF, 1) + String(" ºF") )
display.display();
}
// AUTO RANGE BUTTON
BLYNK_WRITE(vPIN_BUTTON_AUTORANGE) {
autoRange = param.asInt();
display_data();
}
// the stopwatch counter which is run on a timer
void stopwatchCounter() {
stopwatch++;
long days = 0, hours = 0, mins = 0, secs = 0;
String secs_o = ":", mins_o = ":", hours_o = ":";
secs = stopwatch; //convect milliseconds to seconds
mins = secs / 60; //convert seconds to minutes
hours = mins / 60; //convert minutes to hours
days = hours / 24; //convert hours to days
secs = secs - (mins * 60); //subtract the coverted seconds to minutes in order to display 59 secs max
mins = mins - (hours * 60); //subtract the coverted minutes to hours in order to display 59 minutes max
hours = hours - (days * 24); //subtract the coverted hours to days in order to display 23 hours max
if (secs < 10) secs_o = ":0";
if (mins < 10) mins_o = ":0";
if (hours < 10) hours_o = ":0";
// Blynk.virtualWrite(vPIN_ENERGY_TIME, days + hours_o + hours + mins_o + mins + secs_o + secs);
}
/****************************************************************************/
void setup() {
Serial.begin(115200);
// initialize OLED display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(12,25);
display.print("Open Green Energy");
display.display();
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
sensors.begin();
// TIMERS
pollingTimer = timer.setInterval(1000, get_sensor_data);
graphTimer = timer.setInterval(4000, []() {
Blynk.virtualWrite(vPIN_CURRENT_GRAPH, current_mA);
});
stopwatchTimer = timer.setInterval(1000, stopwatchCounter);
// setup split-task timers so we dont overload ESP
// with too many virtualWrites per second
timer.setTimeout(200, []() {
sendTimer1 = timer.setInterval(2000, display_data);
});
// start in auto-range mode & sync widget to hardware state
autoRange = 0;
Blynk.virtualWrite(vPIN_CURRENT_GRAPH, 1);
Blynk.virtualWrite(vPIN_ENERGY_PRICE, String(energyPrice, 4) );
}
/****************************************************************************/
void loop() {
// the loop... dont touch or add to this!
Blynk.run();
timer.run();
}
Hali! 63-65 sorokat jól beállítottad?
A programodat rakosgasd tele Serial.print-el, akkor látod merre kóvályog a progi...
Hello!
Köszi a hozzászólást az igazából nem is kellene hogy én telefonon nézegessem a mért értékeket.
Ez a program arra való, hogy online nézegess dolgokat, direktbe becsattanan Blynkbe, ha ezek nincsenek beállítva, akkor a 232. sorban nem tud csatlakozni és megdöglik. Ha nem szeretnéd ezt, hanem elég a kijelző, akkor az összes blynk hívást írtsd ki belőle.
Hello!
Kiírtottam a Blynk hívásokat és láss csodát működik a dolog!
Köszönöm!
Sziasztok még új vagyok Arduinoban. Valaki tudna segíteni? Hogyan tudok egy változót 1 tizedesre korlátozni? Például egy float típusú humidity értékét 2 tizedes pontossággal kapom meg de nem kell nekem 2 tizedes pontosság.
Köszönöm szépen a tft.printf("%.1f", humidity) valóban levágja egy tizedesre az értékét.
Arra nem emlékszem, hogy kerekít-e vagy csak levágja a századot, teszteld meg... Ha csak levágja esetleg adj hozzá az értékhez 0.05-öt, akkor "kerekítős" lesz
Nem baj ha levágja ez egy mért hőmérséklet és páratartalom értéke nekem teljesen jó levágva is.
Csak az első tizedest írasd ki ...
Üdv.
Mennyire bonyolult úgy beállítani az arduinot hogy böngésző segítségével lássam. Wifis csatlakozás.
Hőmérés adatokat szeretném nézni.
A másik dolog az hogy programozni wifis kapcsolaton keresztül lehet? De ez már csak mint kíváncsiság(lustaság) miatt kérdem.
Idézet: „A másik dolog az hogy programozni wifis kapcsolaton keresztül lehet?”
Ezt hogy érted? Távoli asztal kapcsolattal lehet de koránt sem biztonságos!!!
Sziasztok!
Redőnyt szeretnék automatizálni. ASA motorral van szerelve, a bajom az, hogy 433,24 MHz-en működik. Az egy dolog, hogy nem találok transmittert ilyen frekvenciával, de rezonátort sem, hogy esetleg ki tudnám cserélni a transmitteren. Van valakinek ötlete a hogyan továbbról?
Köszi
P.
Szia!
Feltételezem hogy esp8266 vagy esp32 vezérlőt használsz. Ezekre rengeteg találatot ad a google. Vannak egészen egyszerű példák is, amiket könnyű kipróbálni.
Wifin programozni lehetséges ezeket. Innen elindulhatsz.
|
|