This shows you the differences between two versions of the page.
|
pm:prj2023:alexau:smart-temperature-alarm [2023/05/27 11:52] andrei_stefan.fotin [Hardware Design] |
pm:prj2023:alexau:smart-temperature-alarm [2023/05/27 12:04] (current) andrei_stefan.fotin [Software Design] |
||
|---|---|---|---|
| Line 30: | Line 30: | ||
| </note> | </note> | ||
| - | {{:pm:prj2023:alexau:smart_temperature_alarm.jpg?750x700| Schema in Tinkercad}} | + | {{:pm:prj2023:alexau:smart_temperature_alarm.jpg?775x700| Schema in Tinkercad}} |
| - | {{:pm:prj2023:alexau:smart_temperature_alarm_schematic.jpg?750x746| Schema in Tinkercad}} | + | {{:pm:prj2023:alexau:smart_temperature_alarm_schematic.jpg?775x746| Schema in Tinkercad}} |
| ===== Software Design ===== | ===== Software Design ===== | ||
| - | |||
| <note tip> | <note tip> | ||
| - | Descrierea software a aplicaţiei: | ||
| - | |||
| Aplicatia utilizeaza 2 Arduino Uno, care comunica prin I2C. | Aplicatia utilizeaza 2 Arduino Uno, care comunica prin I2C. | ||
| Fiecare are rolul sau: | Fiecare are rolul sau: | ||
| - | * Slave-ul primeste temperatura de la Master si o afiseaza pe LCD. | + | * Slave-ul primeste temperatura de la Master si o afiseaza pe LCD. |
| - | * Master-ul reprezinta efectiv alarma de temperatura. | + | * Master-ul reprezinta efectiv alarma de temperatura. |
| - | </note> | ||
| - | <note tip> | + | Mediu de dezvoltare: |
| - | Slave Source Code | + | * Arduino IDE |
| - | + | * Tinkercad | |
| - | /** SLAVE **/ | + | |
| - | #include <LiquidCrystal.h> | + | |
| - | #include <Wire.h> | + | |
| - | + | ||
| - | // The slave address to which this master will send data | + | |
| - | #define I2C_SLAVE_ADDRESS 0x09 | + | |
| - | + | ||
| - | // The byte variable in which I2C reads from the master are performed | + | |
| - | int i; | + | |
| - | signed int aux; | + | |
| - | int temp; | + | |
| - | const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; | + | |
| - | LiquidCrystal lcd(rs, en, d4, d5, d6, d7); | + | |
| - | + | ||
| - | void setup() { | + | |
| - | lcd.begin(16, 2); | + | |
| - | lcd.print("Buna ziua!"); | + | |
| - | Wire.begin(I2C_SLAVE_ADDRESS); | + | |
| - | } | + | |
| - | + | ||
| - | void receiveEvent(int numBytes) { | + | |
| - | i = 3; | + | |
| - | temp = 0; | + | |
| - | while (0 <= i) { | + | |
| - | aux = Wire.read(); | + | |
| - | if (aux > 127) { | + | |
| - | aux = aux - 256; | + | |
| - | } | + | |
| - | temp = temp + pow(10, i) * aux; | + | |
| - | i--; | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | void loop() { | + | |
| - | Wire.onReceive(receiveEvent); | + | |
| - | if (temp != 0) { | + | |
| - | lcd.clear(); | + | |
| - | lcd.print("Temp refresh"); | + | |
| - | delay(500); | + | |
| - | lcd.clear(); | + | |
| - | lcd.print(temp / 100); | + | |
| - | lcd.print("."); | + | |
| - | lcd.print(abs(temp % 100)); | + | |
| - | lcd.print(" grade C"); | + | |
| - | delay(5000); | + | |
| - | } | + | |
| - | } | + | |
| </note> | </note> | ||
| - | <note tip> | + | ===== Source Code & Documentation ===== |
| - | Master Source Code | + | |
| - | + | ||
| - | /** MASTER **/ | + | |
| - | #include <Wire.h> | + | |
| - | #include <Keypad.h> | + | |
| - | + | ||
| - | // The slave address to which this master will send data | + | |
| - | #define I2C_SLAVE_ADDRESS 0x09 | + | |
| - | + | ||
| - | // Hardware interrupt time (s) | + | |
| - | #define INTERRUPT_TIME 5 | + | |
| - | + | ||
| - | // KEYPAD MACROS | + | |
| - | const byte numRows = 4; // number of rows on the keypad | + | |
| - | const byte numCols = 4; // number of columns on the keypad | + | |
| - | + | ||
| - | // keymap defines the key pressed according to the row and columns just as appears on the keypad | + | |
| - | char keymap[numRows][numCols] = | + | |
| - | { | + | |
| - | {'1', '2', '3', 'A'}, | + | |
| - | {'4', '5', '6', 'B'}, | + | |
| - | {'7', '8', '9', 'C'}, | + | |
| - | {'*', '0', '#', 'D'}}; | + | |
| - | + | ||
| - | // Code that shows the the keypad connections to the arduino terminals | + | |
| - | byte rowPins[numRows] = {9, 8, 7, 6}; // Rows 0 to 3 | + | |
| - | byte colPins[numCols] = {5, 4, 3, 2}; // Columns 0 to 3 | + | |
| - | + | ||
| - | // initializes an instance of the Keypad class | + | |
| - | Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols); | + | |
| - | char keypressed; | + | |
| - | + | ||
| - | // TEMPERATURE ALARM MACROS | + | |
| - | int REF_HIGH_TEMP = 24; | + | |
| - | int aux_temp; | + | |
| - | float temp; | + | |
| - | int out; | + | |
| - | float vout; | + | |
| - | float vout1; | + | |
| - | int LED = 13; | + | |
| - | int piezo = 10; | + | |
| - | int o1, o2, o3, o4; | + | |
| - | + | ||
| - | volatile bool timerFlag = false; | + | |
| - | bool temperature_set_flag = false; | + | |
| - | bool first_digit_input = false; | + | |
| - | bool second_digit_input = false; | + | |
| - | + | ||
| - | void setup() | + | |
| - | { | + | |
| - | Serial.begin(9600); | + | |
| - | pinMode(A1, INPUT); | + | |
| - | pinMode(LED, OUTPUT); | + | |
| - | pinMode(piezo, OUTPUT); | + | |
| - | + | ||
| - | // Configure Timer1 | + | |
| - | cli(); // Disable interrupts | + | |
| - | TCCR1B = 0; // Clear TCCR1B register | + | |
| - | TCNT1 = 0; // Initialize counter value to 0 | + | |
| - | + | ||
| - | // Calculate the compare match value for 5 seconds at prescaler 1024 | + | |
| - | // The formula is: compareMatch = (clockFreq * interruptDuration) / prescaler - 1 | + | |
| - | // Assuming a clock frequency of 16MHz | + | |
| - | uint16_t compareMatch = ((16000000UL * INTERRUPT_TIME) / 1024) - 1; | + | |
| - | + | ||
| - | OCR1A = compareMatch; // Set compare match value | + | |
| - | TCCR1B |= (1 << WGM12); // Set CTC mode | + | |
| - | TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler to 1024 | + | |
| - | TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt | + | |
| - | + | ||
| - | Wire.begin(); | + | |
| - | sei(); // Enable interrupts | + | |
| - | } | + | |
| - | + | ||
| - | bool isDigit(char keypressed){ | + | |
| - | if (keypressed >= 48 && keypressed <= 57) { | + | |
| - | return true; | + | |
| - | } | + | |
| - | return false; | + | |
| - | } | + | |
| - | + | ||
| - | void loop() | + | |
| - | { | + | |
| - | keypressed = myKeypad.getKey(); | + | |
| - | if (keypressed == 'A') | + | |
| - | { | + | |
| - | Serial.println("Setting the ref temp"); | + | |
| - | temperature_set_flag = false; | + | |
| - | while (temperature_set_flag == false) | + | |
| - | { | + | |
| - | first_digit_input = false; | + | |
| - | second_digit_input = false; | + | |
| - | while (first_digit_input == false) | + | |
| - | { | + | |
| - | keypressed = myKeypad.getKey(); | + | |
| - | if (keypressed != NO_KEY && isDigit(keypressed)) | + | |
| - | { | + | |
| - | //transform from ascii to number | + | |
| - | aux_temp = (keypressed - 48) * 10; | + | |
| - | Serial.println(keypressed); | + | |
| - | first_digit_input = true; | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | while (second_digit_input == false) | + | |
| - | { | + | |
| - | keypressed = myKeypad.getKey(); | + | |
| - | if (keypressed != NO_KEY && isDigit(keypressed)) | + | |
| - | { | + | |
| - | aux_temp = aux_temp + (keypressed - 48); | + | |
| - | REF_HIGH_TEMP = aux_temp; | + | |
| - | Serial.println(keypressed); | + | |
| - | second_digit_input = true; | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | Serial.print("Ref temperature set to: "); | + | |
| - | Serial.println(REF_HIGH_TEMP); | + | |
| - | temperature_set_flag = true; | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | if (timerFlag) | + | |
| - | { | + | |
| - | timerFlag = false; | + | |
| - | + | ||
| - | vout = analogRead(A1); | + | |
| - | vout1 = (vout / 1023.0) * 5000; | + | |
| - | temp = (vout1 - 500) / 10.0; | + | |
| - | + | ||
| - | if (temp >= REF_HIGH_TEMP) | + | |
| - | { | + | |
| - | digitalWrite(LED, HIGH); | + | |
| - | digitalWrite(piezo, HIGH); | + | |
| - | } | + | |
| - | else | + | |
| - | { | + | |
| - | digitalWrite(LED, LOW); | + | |
| - | digitalWrite(piezo, LOW); | + | |
| - | } | + | |
| - | + | ||
| - | out = temp * 100; | + | |
| - | o1 = out / 1000; | + | |
| - | o2 = (out / 100) % 10; | + | |
| - | o3 = (out / 10) % 10; | + | |
| - | o4 = out % 10; | + | |
| - | + | ||
| - | Wire.beginTransmission(I2C_SLAVE_ADDRESS); | + | |
| - | Wire.write(o1); | + | |
| - | Wire.write(o2); | + | |
| - | Wire.write(o3); | + | |
| - | Wire.write(o4); | + | |
| - | Wire.endTransmission(); | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | // Timer1 compare match interrupt service routine | + | |
| - | ISR(TIMER1_COMPA_vect) | + | |
| - | { | + | |
| - | timerFlag = true; | + | |
| - | } | + | |
| - | \</note> | + | |
| - | + | ||
| - | ===== Rezultate Obţinute ===== | + | |
| - | + | ||
| - | <note tip> | + | |
| - | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | |
| - | </note> | + | |
| - | + | ||
| - | ===== Concluzii ===== | + | |
| - | + | ||
| - | ===== Code Source & Documentation ===== | + | |
| - | + | ||
| - | <note> | + | |
| https://github.com/StefanFotin23/Smart-Temperature-Alarm-Arduino | https://github.com/StefanFotin23/Smart-Temperature-Alarm-Arduino | ||
| - | </note> | ||
| - | |||
| - | |||
| - | ===== Bibliografie/Resurse ===== | ||
| - | |||
| - | <note> | ||
| - | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | ||
| - | </note> | ||
| - | |||
| - | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | ||