-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainerEsp32.py
More file actions
204 lines (157 loc) · 16.1 KB
/
Copy pathMainerEsp32.py
File metadata and controls
204 lines (157 loc) · 16.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import network #The libarrey is used for connecting to a wifi network
import socket #Used for communicating back and forth with the Ras-Pi b4
import time #We will use the libarery For all of the time related stuff (except inner socket functions)
from machine import Pin, SoftI2C, ADC #The machine libarery is used for All of the i2c scensors & being able to configure pins(for power, Data, and ADC Functions(Reading power))
import BME280 #A libarery to control the BME 280 sensor
import dht #This libarery is used for beeing able to mssure with the DHT11 Sensor
from machine_i2c_lcd import I2cLcd #This libarery will be used to controll and transmit data to the i2c 16X2 LCD Display
wifi = network.WLAN(network.STA_IF) #It Configeres the Wifi to be a Client(Station Interferace)
wifi.active(True) #It activates the wifi
wifi.connect('Amal1-Student','Amal1@st') #It Gives the Wifi name & Pasword That it is best to connect to, and it connects to it
while not wifi.isconnected(): #while the Wifi is not connectied
time.sleep(0.1) #It waits for 0.1 Seconds
print("Connected to Wi-Fi") #It prints that it is conneected to the wifi
print("ESP32 IP Address:", wifi.ifconfig()[0]) #It Displays the current IP addres of the Esp32(and only the IP addrres [0])
adc_motor = ADC(Pin(34)) #It declares that the Analog Messuring wind speed is connected to pin 34
adc_motor.atten(ADC.ATTN_11DB) #IT gives the Sensor The largest Range, TO get data (Also it is The bigest option)
adc_motor.width(ADC.WIDTH_12BIT) #It creates The posiblaty of (0-2^12-1) Options Of Voltage Value
hall_sensor1 = Pin(27, Pin.IN, Pin.PULL_UP) #It delares For the First Hall Efect sensor To be connectecd to Pin 27 To be an Input Pin, Adn When a magnet pases it will be equell to A eqwivalent of Low
hall_sensor2 = Pin(26, Pin.IN, Pin.PULL_UP) #It delares the Variable For the Seccond annometers hall effect sensor,It configures Pin 26 to be an Input Pin & When a magnet pases it will Return An equivalent of Low
TimeOld1 = None #It declare a variable for The old time that would be in used to messure annometer 1
TimeNow1 = None #IT craters a variable to messurea new time for the first annometer
TimeOld2 = None #It renders new var to be used to caclulate the Prior time in the first annometer
TimeNow2 = None #It makes a new variable that would be used in caclulating the Newest time posible
pulse_count = 0 #A variable to cound pulses
MAGNETS = 2 #The number of magnets blocks on the Annometer's
CIRCUMFERENCE = 0.5 #The circumprence of the blades from the neutral ppoin(0) in Centi-Meters (5 cm)
MagnetsApreance1 = [] #It saves Magnets Aperense To alist for the First annometer (1)
MagnetsApreance2 = [] #It saves Magnets Aperense To another list for the Second annometer (2)
hall_sensor1.irq(trigger=Pin.IRQ_FALLING, handler=count_pulse1) #When the signal from the first HaLL Effect sensor is 0(low) it activates the chain that will caculate the first annometers speed
hall_sensor2.irq(trigger=Pin.IRQ_FALLING, handler=count_pulse2) #When the siganl is not present in the hall effect sensor, it activates the functions in the aproces of caculating the wind speed in annometer 2
i2c = SoftI2C(sda=Pin(21), scl=Pin(22), freq=400000) #It sets up the i2c in the system, and the pins(21 Sda and 22 Scl), And the speed to be 400k [hz]
bme = BME280.BME280(i2c=i2c, address=0x76) #It Asighnes the BME 280 with an i2c Addrres
dht_sensor = dht.DHT11(Pin(14)) #It decaleres the DHT11 Pin to be Pin 14
Raspberry_ip = '192.168.134.100' #It Configurs the Ras-Pi IP that the socket will conect to
Raspberry_port_input = 6020 #It declares a Inport port for the Rasbpery Pi Data inflow
Raspberry_port_output = 6010 #It declares a Output port for the Rasbperry Pi's Output
RunExper = False #It declares the variable RunExper(Run the Expirament) False
OldTime = time.time() #It Saves to avariable the Current time(as old time)
NewTime = time.time() #The variable saves the Curent time
def measure_wind_speed_dc():#הפונקציה מחשבת את המהירות שמתקבלת בצורה אנלוגית מהמנוע(ADC)
raw = adc_motor.read() #It stores the exact value(in Analog temes) that the motor genarates(for futer clacls)
print(raw, "======") #It prints out the 'raw' Variable Value excidecd by an block of ===
voltage = (raw / 4095) * 3.3 #It calculates the precise Volatage(out of 2^12 Options from the raw var) Adjusted to the Esp32 3.3V Scale
ADC_wind_speed = voltage * 1.2 #It calibarates the Wind Speed by the Voltage Genarted and detected by the ADC Input
return round(ADC_wind_speed, 2) #It returns the Rounded Value of the wind speed(Gotten throgh the adc)
def count_pulse1(): #הפונקציה היא חלק מתהליך של מדידת המהירות של האננומטר הראשון
global TimeOld1 #It declares the Time old Variable to be acsesable and beeing ready for reading and writing to the variable in the function
TimeNow1 = time.time() #It calculates the Current Time
if TimeNow1 is not None and TimeOld1 is not None: #If there is now time data it skips this TIme caclulations(for the delta)
TimeDelta = TimeNow1 - TimeOld1 #The Time Delta Finds the Diffarence Betweenn the difarent times
MagnetsApreance1.append(TimeDelta) #It adds data to the time delta list
if len(MagnetsApreance1) > 4: #It makes sure that there are not more then 4 mesuments
MagnetsApreance1.pop(0) #It Deleates the oldest value(The first one in the list), To not over do it
TimeOld1 = TimeNow1 #It changes the time value, so the old time will be relevant for the next loop
if len(MagnetsApreance1) == 4: #If there are 4 values(2 rotation time values) in the list
TimeOld1 = TimeNow1 #It helps it the second time
measure_wind_speed1() #It activates the function to messure the Hall effect messured Wind speed
TimeOld1 = TimeNow1 #In the first time, it makes sure the loop could work so it could work the second time
def measure_wind_speed1(): #הפונקציה מחזירה את המהירות העדכנית ביותר של האננומטר הראשון
AvrCurrentTimeWindSpeed1 = sum(MagnetsApreance1) / len(MagnetsApreance1) #Average time between detections
frequency = 1 / AvrCurrentTimeWindSpeed1 #Magnet passes per second T^(-1)
rps = frequency / MAGNETS #Rotations per second
WindSpeed1 = rps * CIRCUMFERENCE #It calculates the Wind speed in decimetaers per second
return (WindSpeed1) #It returns the wind speed of the first annometer
def count_pulse2(): #הפונקציה היא גם חלק מתהליך אחר של מציאת המהירות באננומטר השני
global TimeOld2 #It makes sure the the new time variable for the second annometer could be wrtien to and from it
TimeNow2 = time.time() #It calculates the Current Time
if TimeNow2 is not None and TimeOld2 is not None: #If both of the Time caclculating Times have avalue so it would not just calculate nothing
TimeDelta2 = TimeNow2 - TimeOld2 #The Time Delta Finds the Diffarence Betweenn the difarent times
MagnetsApreance2.append(TimeDelta2) #It appends the newest time deta in order to calcularte it better
if len(MagnetsApreance2) > 4: #IT makes sure that there are not more then 4 mesuments
MagnetsApreance2.pop(0) #It deleates the oldest entry/index in order to clean up and get more data
TimeOld2 = TimeNow2 #It Changes the Old time to be the current time in order for it to be changed later
if len(MagnetsApreance2) == 4: #If the List is 4 entries long(then)
TimeOld2 = TimeNow2 #IT Changes the Old time to be the current timr in order for it to be changed later
measure_wind_speed2() #It activates the Wind Speed Mesuring function
TimeOld2 = TimeNow2 #In case it is the first loop, It gives it atime so it could work the second time
def measure_wind_speed2(): #הפונקציה מוצאת את המהירות העכשיות של האננומטר השני
AvrCurrentTimeWindSpeed2 = sum(MagnetsApreance2) / len(MagnetsApreance2) #Average time between detections
frequency = 1 / AvrCurrentTimeWindSpeed2 #Magnet passes per second T^(-1)
rps = frequency / MAGNETS #Rotations per second
WindSpeed2 = rps * CIRCUMFERENCE #It calculates the Wind speed in decimetaers per second
return (WindSpeed2) #It returns the Wind Speed
GetConnection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Establishes an Connection socket input and Output socket using the AF_init protocol(Ipv4), and socket stream, to start and stop
GetConnection.bind(("0.0.0.0", Raspberry_port_input)) #It binds compleatly the Esp32 Socket for conection and it always routs the Ras-Pi requests to the same place(0.0.0.0 Acesible for everyone)
GetConnection.listen(1) #It would be afective only for a single connection
Raspberry_socket_output = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Establishes with the Ras-Pi an 2 way socket using (Ipv4) throguh AF_init protocol, and socket stream to comunicate with the Rasbperry Pi
Raspberry_socket_input = None #without an Value Beasue it still is not its time
lcd_address = i2c.scan()[0] #It surches for the first Place(addrres) that the LCD could put itsef
lcd = I2cLcd(i2c, lcd_address, 2, 16) #It configures the LCD to be in ai2c Comunication, in the previously found Addrress, in a 16X2 Grid(מערך)
def StartConnections(): #הפונקציה יוצרתחיבור אם הראסברי פאי(Ras-pi-4b)
global Raspberry_socket_input #It declares the Ras-pi socket input socket as a global variable(beeing able to acsess it in the func)
try: #The Try nlock here is for connecting to asocket (sockets have alot {and i mean alot} of problams connecting)
Raspberry_socket_input, Ussless = GetConnection.accept() #It creates The connectein with the ESP32 Being theserver and the ras-PI as the reciving client
print("got the connection") #It Prints to the user the it got the connection
Raspberry_socket_output.connect((Raspberry_ip, Raspberry_port_output)) #It makes the connection between the Ras-Pi as the Server and the esp32 As the reciving client
print("Connections established successfully") #It prints that the connection was establisht seucssefully
Raspberry_socket_input.settimeout(2) #IT gives the ras-pi extra time To send more data in case of an desterbence in the Ras-Pi sending function
reciveFromRaspberry() #It starts the function To Recive data From the Ras Pi
except Exception as e:#If there was sn error it Saves the error as e
print(e) #It displaies to the user that error
def SortMessegeFromR(data): #הפונקציה ממינת את ההודעה שהתקבלה מהRas-Pi
global RunExper #It declares the Run (the) Expirament Variable as a global variable(acsesible for reading and changeing it in and out of this function)
messege = data.decode('utf-8').strip() #IT convertes the incoming data in to the utf-8 data(from bits, to humen understood) And it polishis it up(taking out comas, slahes and stuff like that)
lcd.clear() #It clears The Output on the LCD
lcd.putstr(messege[:32]) #It Displais the message var on the lcd screen in its limitations(32 characters 2X16)
if messege == "StartExper": #If the message That it got from the Ras-Pi is StartExpers
print("starting exper") #It displaies to the user Starting Exper
RunExper = True #It declares the VAr Run experiment to be true
StartExperiment() #And it starts the function Startexperiment()
elif messege == "StopExper": #If the message it got from the Rasbpeery pi socket is Stop Experiment
print("stoping exper") #It prints the message to the user stoping experimetn
RunExper = False #It decalres the Variable of running the expirament false
SendToRaspberry("ExperStoped") #It Sends the Signal to the ras-pi through the socket that the expirmanet has ended
else: #If there wasn't a message
pass #It forfits the Fnction
def reciveFromRaspberry(): #הפונקציה מקבלת מידע מהראסברי פאי, והיא שולחת אותה למיון
global Raspberry_socket_input #It declares the Ras Socket input to be aglobal variable so it could be Writen and read Inide and outide of the function
print("receiving") #It prints to The program Userthe MEssage Recive
while True: #While the Block is not disrupted It will always loop over
try: #It will always start with a tryt block to get data from the esp32
data = Raspberry_socket_input.recv(8192) #The data Recived is up to 8(kb) And it is asgined to the data Variable
if data: #If any data was recived
SortMessegeFromR(data) #It Sends the data to the Sorting Fuction
except Exception as e: #In case of problemes it saves them as e
print(f"The Ecception was- {e}") #It prints here the exeption Before
def SendToRaspberry(messege): #הפונקציה שולחת את המידע שהתקבל מהסנסורים לראסברי פאי
if isinstance(messege, str): #it CHECKS ever the MEssage is saved as A String
messege = messege.encode('utf-8') #It Encodes(changes to that) the data in to the utf-8 format
Raspberry_socket_output.send(messege) #It sends throught the ras Pi Output soket the message(sensor data)
def StartExperiment(): #הפונקציה היא הפונקציה הראשית שאחראית אל איסוף, תצוגה וסדר הפעולות של כמעת כל התוכנה
global RunExper #It Declares the Run Expirament Variable to Be golbal(Beiing able to read And write to a Variable that was not created inside of the Fucntion)
print("==-- starting reading the data from the sensors --==") #It prints a message about Starting to read Data from the Sensors
while True: #While The Fucntion dose not break(stop)
try: #It makes a Try block that it mains pourpous is to caclculate the Current Data From the Sensors
sleep(0.35) #It sleeps for 350 Mili Seconds to give the system alitle bit of abuffer so all of the sensors could have alitle time for more acuret messurements
temp_bme = float(bme.temperature[:-1]) #It Mesures the Temp through the BME280 But it takes out the Celcius(C) OUt of the result, and it converts to a flote variable
press = float(bme.pressure[:-3]) #It mesars the BME280 presure and it removes the Units(hPe), and it converts it to afully floating number
dht_sensor.measure() #It gives the DHT11 Sensor more time to refresh
temp_dht = dht_sensor.temperature() #It caclculates the Tempeture Through the DHT11 Senosr
hum = dht_sensor.humidity() #It Calculates the humidty througgh the DHT 11 Sensor
avg_temp = round((temp_bme + temp_dht) / 2, 1) #It calculates the Avarege Tempeture For both Sensing(BME280 +Dht11) Sensors
speed_before = measure_wind_speed1() #Speed Before is Calculated through the first Annometer Wind Speed Calculation Function
speed_after = measure_wind_speed2() #Speed After is Calculateed throguh the Function to calculate the wind speed
Delta_speed = speed_before - speed_after #The delta Speed is the Speed Difarence Before and after
speed_dc = measure_wind_speed_dc() #It calculate the First annometer speed Through the Fucntion to caclulate the ADC Annometer calculation
wind_speed = (speed_before + speed_dc) / 2 #It calculates the Avarege Wind Speed (Of the first annometer)
BigStr = "Data,{},{},{},{},{}".format(avg_temp, press, hum, wind_speed,Delta_speed) #It Puts The Updated Sensore data in to long Big String
print(BigStr) #It Prints the Data Gathered
lcd.clear() #It cleares the LCD's Screen from any message Displaied
lcd.putstr(BigStr[:32]) #It Displays upon the LCD Screen the Big String data variable, But up to 32 Characters (the 16*2 Screen maximum Capacity for characters)
SendToRaspberry(BigStr) #It sends To the function that sends the senosrs data
reciveFromRaspberry() #Ir Starts the Function That recives Data from the Rasbperry Pi
except Exception as E: #It saves the problam(Exception) In the Vaiable E
print("Error:", E) #It prints the error that it got And The Error it saved as E
break #It breaks the for loop
StartConnections() #it starts the Main fuction to get connections through