Untitled
unknown
plain_text
a year ago
10 kB
4
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