This is an old revision of the document!
Proiectul constă în implementarea unui sistem de reglaj a turației unui motor în funcție de temperatura ambientală.
Motorul DC este conectat la pini expuși de un Arduino Nano. Acesta folosește Pulse-Width-Modulation pentru a schimba turația motorului, prin intermediul unei punți H (L293D).
În aceiași încăpere cu motorul se află un senzor de temperatură (DHT11), iar în funcție de valoarea citită de la senzor se vor executa una din următoarele acțiuni:
Am utilizat următoarele componente:
Toate componentele sunt alimentate la 5V, direct din pinul de power al microcontrollerului. Cu toate acestea comanda și citirea se face prin intermediul piniilor GPIO, care lucrează la 3.3V.
Piese:
<code cpp>
#include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Wire.h>
#define SCREEN_WIDTH 128 OLED display width, in pixels #define SCREEN_HEIGHT 32 #define SCREEN_ADDRESS 0x3C #define OLED_RESET 11 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #include <DHT.h> #define DHTTYPE DHT11 #define DHTPIN 2 #define MOTORSPEED 11 #define DIRA 8 #define DIRB 7 #define DELAY_OFF (1.5 * 1000) #define DELAY_MEDIUM (3 * 1000) #define DELAY_FAST (5 * 1000) #define BUZZER 3 #define PWM_FILL 112 #define GREEN 6 #define YELLOW 5 #define RED 4 DHT dht(DHTPIN, DHTTYPE, 6); #include “RTClib.h” RTC_PCF8523 rtc; char daysOfTheWeek[7][12] = {“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}; struct status { float temp; float humi; }; void init_leds(void) { pinMode(GREEN, OUTPUT); pinMode(YELLOW, OUTPUT); pinMode(RED, OUTPUT); digitalWrite(GREEN, LOW); digitalWrite(YELLOW, LOW); digitalWrite(RED, LOW); } void init_motor(void) { pinMode(MOTORSPEED, OUTPUT); analogWrite(MOTORSPEED, 0); } void init_buzzer(void) { pinMode(BUZZER, OUTPUT); analogWrite(BUZZER, 0); } void init_rtc(void) { if (!rtc.begin()) { Serial.println(“Couldn't find RTC”); } if (!rtc.initialized() || rtc.lostPower()) { Serial.println(“RTC is NOT initialized, let's set the time!”); rtc.adjust(DateTime(F(DATE), F(TIME))); } rtc.start(); float drift = 43; seconds plus or minus over oservation period - set
// to 0 to cancel previous calibration.
float period_sec =
(7 * 86400); // total obsevation period in seconds (86400 = seconds
// in 1 day: 7 days = (7 * 86400) seconds )
float deviation_ppm = (drift / period_sec *
1000000); // deviation in parts per million (μs)
float drift_unit = 4.34; // use with offset mode PCF8523_TwoHours
int offset = round(deviation_ppm / drift_unit);
Serial.print("Offset is ");
Serial.println(offset); // Print to control offset
}
void setup() {
Serial.begin(57600);
init_leds();
init_motor();
init_buzzer();
dht.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
}
display.display();
delay(2000);
display.clearDisplay();
init_rtc();
}
void turn_off(void) {
analogWrite(MOTORSPEED, 0);
digitalWrite(DIRA, LOW);
digitalWrite(DIRB, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
analogWrite(BUZZER, PWM_FILL);
delay(DELAY_OFF);
analogWrite(BUZZER, 0);
}
void turn_medium(void) {
analogWrite(MOTORSPEED, 100);
digitalWrite(DIRA, HIGH);
digitalWrite(DIRB, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, HIGH);
digitalWrite(RED, LOW);
delay(DELAY_MEDIUM);
}
void turn_fast(void) {
analogWrite(MOTORSPEED, 200);
digitalWrite(DIRA, HIGH);
digitalWrite(DIRB, LOW);
digitalWrite(GREEN, HIGH);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
delay(DELAY_FAST);
}
status get_status(void) {
float temp = dht.readTemperature();
float humi = dht.readHumidity();
Serial.print("Temperature = ");
Serial.println(temp);
Serial.print("Humidity = ");
Serial.println(humi);
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.print(F("Temp = "));
display.println(temp);
display.print(F("Humi = "));
display.println(humi);
DateTime now = rtc.now();
display.print(now.year());
display.print('/');
display.print(now.month());
display.print('/');
display.print(now.day());
display.print(' ');
display.print(daysOfTheWeek[now.dayOfTheWeek()]);
display.println();
display.print(now.hour());
display.print(':');
display.print(now.minute());
display.print(':');
display.print(now.second());
display.println();
display.display();
return {temp, humi};
}
void loop() {
status s = get_status();
if (s.temp > 40) {
turn_off();
} else if (s.temp > 30) {
turn_medium();
} else {
turn_fast();
}
}
<\code>
Am folosit doar bibliotecile Adafruit din Arduino IDE.
poza
În concluzie, consumă mult mai puțin curent decât fostul experiment ce folosea un Rasbery Pi 4B.