Untitled
unknown
plain_text
5 months ago
10 kB
3
Indexable
#include <SoftwareSerial.h> #include <avr/sleep.h> // Biblioteka do zarządzania trybem uśpienia #include <avr/wdt.h> #define powerPIN 7//Arduino Digital pin used to power up / power down the modem #define resetPIN 6//Arduino Digital pin used to reset the modem #define statusPIN 5//Arduino Digital pin used to monitor if modem is powered // Define the RX and TX pins for SoftwareSerial SoftwareSerial gsmSerial(2, 3); // RX, TX const int controlPin = 8; // Pin do podtrzymywania stanu wysokiego #define TF02_RX_PIN 10 // Pin for TF02 sensor RX #define TF02_TX_PIN 11 // Pin for TF02 sensor TX SoftwareSerial tf02Serial(TF02_RX_PIN, TF02_TX_PIN); // SoftwareSerial instance for TF02 sensor #define powerKeyPin 7 // PWRKEY modułu GSM #define converterControlPin 8 // Pin sterujący przetwornicą (stan niski = włącz) // Czas uśpienia (4 godziny) #define SLEEP_TIME 60 // W sekundach (4 * 3600) const int NUM_READINGS = 5; // Number of readings to average uint16_t distanceReadings[NUM_READINGS]; // Array to store distance readings int currentIndex = 0; // Index for storing the current reading uint16_t distance = 0; const int analogPin = A0; // Wejście analogowe, np. A0 volatile bool wakeUp = false; // Flaga wybudzenia // Liczba pomiarów const int NUM_MEASUREMENTS = 16; float data[NUM_MEASUREMENTS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Parametry detekcji odstających wartości const float THRESHOLD_MULTIPLIER = 0.2; // Próg w krotnościach odchylenia standardowego // Funkcje pomocnicze void powerOnGSM(); void powerOffGSM(); float readTF02Pro(); void sendSMS(String phoneNumber, String message); void goToSleep(unsigned long seconds); unsigned long sleepTime = 0; void setup() { Serial.begin(9600); pinMode(powerKeyPin, OUTPUT); pinMode(converterControlPin, OUTPUT); digitalWrite(converterControlPin, HIGH); // Włącz zasilanie czujnika (jeśli sterowane) Serial.println("System uruchomiony."); // Initialize distance readings array for (int i = 0; i < NUM_READINGS; i++) { distanceReadings[i] = 0; } } void loop() { float voltage = readVoltage(analogPin); // Odczytaj napięcie z pinu analogowego Serial.print("Napiecie: "); Serial.print(voltage); Serial.println(" V"); tf02Serial.begin(115200); // UART dla czujnika digitalWrite(converterControlPin, LOW); delay(3000); // Daj czujnikowi czas na stabilizację Serial.println("Wypełnanie tabelki:"); for (int i = 0; i < 16; i++) { distance = readDistanceFromTF02(); if (distance != 0 && distance < 15000) { data[i] = distance;// Kod, który będzie wykonywany dopóki warunek jest prawdziwy Serial.print("zczytano pomiar, Odleglosc: "); Serial.print(distance); Serial.println(" cm"); } else{ Serial.print("Odrzucono pomiar, Odleglosc: "); Serial.print(distance); i--; } } float wynikDoWyslania = odrzucBledne(data, 16); digitalWrite(converterControlPin, HIGH); gsmSerial.begin(57600); // UART dla modułu GSM powerOnGSM(); delay(5000); sendSMS("+48602806856", "Odleglosc wynosi: " + String(distance) + " cm, napiecie baterii wynosi: " + String(voltage) + " V."); sleepTime = 60; // Czas w sekundach Serial.println("Przechodzę w stan uśpienia na 10 sekund..."); delay(1000); preciseSleep(sleepTime); } float odrzucBledne(float pomiary[], int liczbapomiarow){ // Próg w krotnościach odchylenia standardowego const float THRESHOLD_MULTIPLIER = 0.5; int licznikOdrzuconych = 0; Serial.println("Rozpoczynam analizę danych..."); float mean = calculateMean(pomiary, liczbapomiarow); Serial.print("Średnia: "); Serial.println(mean); // Oblicz odchylenie standardowe float stdDev = calculateStandardDeviation(pomiary, liczbapomiarow, mean); Serial.print("Odchylenie standardowe: "); Serial.println(stdDev); Serial.println("Pomiary odrzucone:"); for (int i = 0; i < liczbapomiarow; i++) { if (abs(pomiary[i] - mean) > THRESHOLD_MULTIPLIER * stdDev) { Serial.print("Wartość odstająca: "); Serial.println(pomiary[i]); licznikOdrzuconych += 1; } } Serial.println("Nowa tabelka:"); int roznicaPomiarow = (liczbapomiarow-licznikOdrzuconych); Serial.println(roznicaPomiarow); float poprawionaTabelka[roznicaPomiarow]; int licznikDodanych = 0; for (int i = 0; i < liczbapomiarow; i++) { if (abs(pomiary[i] - mean) < THRESHOLD_MULTIPLIER * stdDev){ Serial.print("Wartość dodana do tabelki: "); Serial.println(pomiary[i]); poprawionaTabelka[licznikDodanych] = pomiary[i]; licznikDodanych += 1; } } float meanFinal = calculateMean(poprawionaTabelka, roznicaPomiarow); return meanFinal; } // Funkcja do obliczenia średniej float calculateMean(float arr[], int size) { float sum = 0; for (int i = 0; i < size; i++) { sum += arr[i]; } return sum / size; } // Funkcja do obliczenia odchylenia standardowego float calculateStandardDeviation(float arr[], int size, float mean) { float sumSqDiff = 0; for (int i = 0; i < size; i++) { sumSqDiff += pow(arr[i] - mean, 2); } return sqrt(sumSqDiff / size); } float readVoltage(int pin) { int analogValue = analogRead(pin); // Odczytaj wartość analogową (0-1023) float voltage = analogValue * (5.0 / 1023.0) * 5.63; // Przeskaluj wartość na zakres napięcia (0-5V) return voltage; } // Function to send AT commands and print responses void sendATCommand(String command) { gsmSerial.println(command); // Send the command to the GSM module delay(100); // Wait for a response while (gsmSerial.available()) { Serial.write(gsmSerial.read()); // Display GSM response on Serial Monitor } } uint16_t readDistanceFromTF02() { // Send command to request distance data tf02Serial.write((uint8_t)0x5A); // Command to request distance data tf02Serial.write((uint8_t)0x05); // Data length tf02Serial.write((uint8_t)0x00); // Data byte 1 tf02Serial.write((uint8_t)0x00); // Data byte 2 tf02Serial.write((uint8_t)0x00); // Data byte 3 tf02Serial.write((uint8_t)0x01); // Data byte 4 // Read response uint8_t response[9]; tf02Serial.readBytes(response, 9); // Check if response is valid if (response[0] == 0x59 && response[1] == 0x59) { // Extract distance data uint16_t distance = (response[3] << 8) | response[2]; // Combine high and low bytes return distance; } else { return 0; // Invalid response, return 0 distance } } // Function to send SMS void sendSMS(String phoneNumber, String message) { // Send an AT command to check if GSM module is responding sendATCommand("AT"); delay(2000); // Set the SMS text mode sendATCommand("AT+CMGF=1"); // Set SMS mode to text delay(2000); // Send the AT command to start the SMS process gsmSerial.print("AT+CMGS=\""); gsmSerial.print(phoneNumber); gsmSerial.println("\""); delay(2000); // Wait for prompt // Send the SMS message gsmSerial.print(message); delay(500); // Send the Ctrl+Z character to indicate end of message (ASCII code 26) gsmSerial.write(26); delay(5000); // Wait for the message to be sent // Print the result of the send operation Serial.println("SMS sent!"); powerOffGSM(); } void powerOnGSM() { Serial.println("Włączam moduł."); digitalWrite(powerKeyPin, LOW); // Pull the power key pin low delay(2000); // Hold it low for 1 second (power on pulse) digitalWrite(powerKeyPin, HIGH); // Release the power key pin delay(10000); // Wait for 2 seconds for module to boot up } void powerOffGSM() { digitalWrite(powerKeyPin, LOW); // release the power key pin low delay(2000); // Hold it low for 1 second (power on pulse) digitalWrite(powerKeyPin, HIGH); // pull the power key pin delay(10000); // Wait for 2 seconds for module to boot up Serial.println("Moduł wyłączony."); } // Funkcja wprowadzająca Arduino w tryb uśpienia na określony czas (w sekundach) void preciseSleep(unsigned long seconds) { const unsigned long WDT_CYCLE = 8; // Maksymalny czas jednego cyklu Watchdog Timer (8 sekund) unsigned long elapsedSeconds = 0; // Licznik czasu, który upłynął while (elapsedSeconds < seconds) { unsigned long remainingSeconds = seconds - elapsedSeconds; unsigned long sleepDuration = (remainingSeconds >= WDT_CYCLE) ? WDT_CYCLE : remainingSeconds; // Uśpij na czas sleepDuration setSleepMode(sleepDuration); // Zaktualizuj upływający czas elapsedSeconds += sleepDuration; } } // Funkcja konfiguracji Watchdog Timer i przejścia w tryb uśpienia void setSleepMode(unsigned long duration) { // Mapowanie czasu na preskaler Watchdog Timer uint8_t wdt_prescaler; if (duration <= 1) wdt_prescaler = WDP0; else if (duration <= 2) wdt_prescaler = WDP1; else if (duration <= 4) wdt_prescaler = WDP2; else if (duration <= 8) wdt_prescaler = WDP3; else return; // Jeśli czas > 8 sekund, użyj wielu cykli // Utrzymywanie stanu wysokiego na pinie 8 digitalWrite(controlPin, HIGH); // Konfiguracja Watchdog Timer cli(); // Wyłącz przerwania MCUSR = 0; // Reset flag Watchdog Timer WDTCSR = (1 << WDCE) | (1 << WDE); // Włącz tryb zmiany ustawień WDT WDTCSR = (1 << WDIE) | wdt_prescaler; // Włącz przerwanie WDT sei(); // Włącz przerwania globalne // Ustawienie trybu uśpienia set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Tryb minimalnego zużycia energii sleep_enable(); // Włącz tryb uśpienia // Przejście w tryb uśpienia sleep_cpu(); // Po wybudzeniu sleep_disable(); // Wyłączenie trybu uśpienia sei(); // Włącz przerwania globalne } // Procedura obsługi przerwania Watchdog Timer ISR(WDT_vect) { Serial.println("Wybudzono z uśpienia!"); wakeUp = true; // Flaga wybudzenia }
Editor is loading...
Leave a Comment