Program níže je program z Arduino Mega. Mám tam připojený modul ESP01 (Serial3), SD card shield, malý 0,96" displej a na pin č. 18 anemometr jako interrupt pin. Cílem je, aby Arduino zaznamenávalo rychlost větru, logovalo ho na paměťovou kartu spolu s provozním časem od zapnutí a zároveň to posílalo na Thingspeak a zobrazovalo na displeji.
Funguje to dobře, nicméně program občas spadne v momentě, kdy je interruptů mnoho, program se zasekne ve funkci Windy. Přemýšlel jsem, jestli to není zápisem na Thingspeak, když jej například interrupt vyruší, ale nevím. Zaseknutí se stane vždy, jen pokaždé v jiný moment.
Neuměli byste, prosím, někdo poradit? Mám v kódu ještě nějaké výpočty pro rychlost větru, které jsou hodny vymazání, protože je už nepoužívám. Jinak jsem program napsal tak, aby se každou periodu měnil název textového souboru, aby Arduino například po týdnu provozu nezapisoval do textového souboru o objemu několika MB, proto jsem to udělal tak, ať se zápisy rozdělí do více souborů. Pro test funkce jsem dal samozřejmě zatím periodu kratší...
Děkuji
Kód: Vybrat vše
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SD.h> //Karta
String myAPIkey = "MOJEAPI";
unsigned short int Mode = 1; // Aktivovaný mód
int ModePeriod = 3600; // Jak často se bude aktivovat nový mód v S
unsigned int ModePeriodLastTime = 0; // Proměnná pro uložení posledního času přepisu módu
String FileName;
String FileNameOriginal = "_Wind.txt"; // Název souboru, který se nebude nikdy měnit
Adafruit_SSD1306 display(-1);
File myFile;
String Version = " WL14";
long int WindPuls = 0; // Při každém pulzu se updatuje
const int PinAnemometer = 18; // Pin anemometru
unsigned int WindyPeriod = 5000; // Perioda v ms, kdy se bude počítat rychlost větru
unsigned long int WindyLastTime = 0; // Poslední čas, kdy byl měřen rychlost větru
int Minutes = 0; // Probíhající minuta
int PreviousMinutes = 0; // Proměnná pro poslední hodnotu
float meterPerSecond = 0; // Rychlost větru
// Proměnné pro ESP
long writingTimer = 17; // Jak často mohu zapisovat na Thingspeak
long startTime = 0; // Váže se k zápisu na Thingspeak
long waitTime = 0; // Váže se k zápisu na Thingspeak
const char* server = "api.thingspeak.com";
int WifiPerioda = 300000; // Jak často v ms se pokusit znovu připojit na WiFi
int WifiLastTime = 0;
unsigned char check_connection=0;
unsigned char times_check=0;
boolean error;
void setup() {
Minutes = (millis()/1000)/60;
pinMode(PinAnemometer, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PinAnemometer), Windy, FALLING); // Pokud dojde k přerušení, volá se funkce Windy
Serial.begin(9600);
Serial3.begin(115200); // Inicializace ESP
startTime = millis();
WiFiInit();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
if (!SD.begin(53)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
ModeReset ();
}
void loop()
{
Minutes = (millis()/1000)/60 - PreviousMinutes;
// Pokud čas dospěje k časové periodě měření, proběhne výpočet rychlosti větru
if (millis() - WindyLastTime >= WindyPeriod)
{
WindyLastTime = millis();
WindCount();
Store();
}
if ((millis()/1000) - ModePeriodLastTime >= ModePeriod)
{
ModeReset ();
ModePeriodLastTime = millis()/1000;
}
waitTime = millis()-startTime;
if (waitTime > (writingTimer*1000))
{
writeThingSpeak();
startTime = millis();
}
if (millis() - WifiLastTime >> WifiPerioda) // Opětovné připojení k WiFi
{
WifiLastTime = millis();
WiFiInit();
}
}
void Windy()
{
WindPuls++;
Serial.print("WindPuls: ");
Serial.println(WindPuls);
}
// Výpočet měření rychlosti větru
void WindCount()
{
int AnemometerRadius = 70; // Poloměr anemometru v mm
int Rotation = WindPuls/2; // Počet otáček anemometru - dva pulzy na jednu otáčku
WindPuls = 0; // Pulzy se začnou počítat znovu
float AnemometerCircle = (2*3.14)*AnemometerRadius; // Obvod anemometru
float AnemometerCircleMetres = AnemometerCircle/1000; // Obvod anemometru do metrů, protože chci rychlost v m/s
float AnemometerMetresRotated = AnemometerCircleMetres * Rotation; // Takové vzdálenosti anemometr zřejmě dosáhl
int WindyPeriodSeconds = WindyPeriod/1000; // WindyPerioda na vteřiny
float WindSpeed = AnemometerMetresRotated / WindyPeriodSeconds;
meterPerSecond = Rotation * (0.66 / WindyPeriodSeconds); // Tato hodnota sedí lépe s anemometrem
Serial.print("meterPerSecond: ");
Serial.println(meterPerSecond);
Serial.print("WindSpeed: ");
Serial.println(WindSpeed);
Serial.println(); // Mezera
DisplayShow(meterPerSecond);
}
void DisplayShow(float meterPerSecond)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Rychlost m/S: ");
display.print(meterPerSecond);
//display.display();
display.setCursor(0, 10);
display.print("M: ");
display.print(Mode);
display.print(Version);
display.setCursor(0, 20);
display.print("Provoz: ");
display.print(Minutes);
if (SD.begin(53))
{
display.setCursor(100, 20);
display.print("SD-A");
}
else
{
display.setCursor(100, 20);
display.print("SD-N");
}
display.display();
}
void Store()
{
Serial.print("Minutes: ");
Serial.println(Minutes);
myFile = SD.open(FileName, FILE_WRITE);
Serial.print("Store, FileName: ");
Serial.println(FileName);
if (myFile)
{
myFile.print(meterPerSecond);
myFile.print(" ");
myFile.print(Minutes);
myFile.println("");
myFile.close();
}
}
void ModeReset () // V této funkci se změní mód, aby Arduino nepracovalo s příliš objemným poznámkovým blokem
{
Mode = Mode + 1;
FileName = int(Mode)+FileNameOriginal; // S novým módem se založí i nový soubor na kartě, aby nevznikl příliš velký soubor
Serial.println("Mode Reset");
PreviousMinutes = (millis()/1000)/60;
}
void writeThingSpeak(void)
{
startThingSpeakCmd();
// preparacao da string GET
String getStr = "GET /update?api_key=";
getStr += myAPIkey;
getStr +="&field1=";
getStr += String(meterPerSecond);
getStr += "\r\n\r\n";
Serial.print("getStr: ");
Serial.println(getStr);
GetThingspeakcmd(getStr);
}
void startThingSpeakCmd(void)
{
Serial3.flush();
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "52.22.110.199"; // api.thingspeak.com IP address // Změna oproti návodu
cmd += "\",80";
Serial3.println(cmd);
Serial.print("Start Commands: ");
Serial.println(cmd);
if(Serial3.find("Error"))
{
Serial.println("AT+CIPSTART error");
return;
}
}
String GetThingspeakcmd(String getStr)
{
String cmd = "AT+CIPSEND=";
cmd += String(getStr.length());
Serial3.println(cmd);
Serial.println(cmd);
if(Serial3.find(">"))
{
Serial3.print(getStr);
Serial.println(getStr);
delay(500);
String messageBody = "";
while (Serial3.available())
{
String line = Serial3.readStringUntil('\n');
if (line.length() == 1)
{
messageBody = Serial3.readStringUntil('\n');
}
}
Serial.print("MessageBody received: ");
Serial.println(messageBody);
return messageBody;
}
else
{
Serial3.println("AT+CIPCLOSE");
Serial.println("AT+CIPCLOSE");
}
}
void WiFiInit() // Nastavení WiFi
{
int TimeNow = millis();
Serial3.println("AT+RST");
Serial3.println("AT+CWMODE=1");
delay(2000);
Serial.println("Connecting to Wifi");
while(check_connection==0)
{
if (millis() - TimeNow >= 15000)
{
Serial.println("Opoustim smycku");
break;
}
Serial.print(".");
Serial3.print("AT+CWJAP=\"Název Wifi\",\"Heslo na Wifi\"\r\n");
Serial3.setTimeout(5000);
if(Serial3.find("WIFI CONNECTED\r\n")==1)
{
Serial.println("WIFI CONNECTED");
break;
}
times_check++;
if(times_check>3)
{
times_check=0;
Serial.println("Trying to Reconnect..");
}
}
}
20:54:24.023 -> writeThingSpeak
20:54:24.023 -> startThingSpeakCmd
20:54:24.063 -> Start Commands: AT+CIPSTART="TCP","52.22.110.199",80
20:54:24.143 -> Windy
20:54:24.143 -> WindPuls: 15
20:54:24.422 -> Windy
20:54:24.422 -> WindPuls: 16
20:54:24.663 -> Windy
20:54:24.663 -> WindPuls: 17
20:54:24.903 -> Windy
20:54:24.903 -> WindPuls: 18
20:54:25.183 -> Windy
20:54:25.183 -> WindPuls: 19
20:54:25.423 -> Windy
20:54:25.423 -> WindPuls: 20
20:54:25.662 -> Windy
20:54:25.662 -> WindPuls: 21
20:54:25.943 -> Windy
20:54:25.943 -> WindPuls: 22
20:54:26.183 -> Windy
20:54:26.183 -> WindPuls: 23
20:54:26.463 -> Windy
20:54:26.463 -> WindPuls: 24
20:54:26.703 -> Windy
20:54:26.703 -> WindPuls: 25
20:54:26.983 -> Windy
20:54:26.983 -> WindPuls: 26
20:54:27.223 -> Windy
20:54:27.223 -> WindPuls: 27
20:54:27.503 -> Windy