Maker/DIY
Engenharia Elétrica
Alguns programinhas
Economia
Assuntos Nerds
Fotografia
The first version I was using a low cost IoT device based on the ESP-8266 module which can be programmed with the Arduino IDE. The main reason to using this is to make Json request from my Web App to handle the food feed time and to manage the time to turn ON/OFF the light and Filter Bomb. The WebApp is very simple. From Arduino point of view we do a request with a URL and parser the Json object to split the information.
First I send a request to the web app with the luminosity intensity from the LDR and after how I handle the Json response.
String url = "http://iottools.marumaker.com/get_resume?ldr=" + statusLido;
HTTPClient http;
Serial.print("Requested Link: ");
Serial.println(url);
http.begin(client, url);
int httpCode = http.GET();
String payload = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
JsonObject obj = doc.as
String status = obj["status"];
StringSplitter *splitter = new StringSplitter(status, ',', 7);
String log_time = splitter->getItemAtIndex(0);
String numero_voltas = splitter->getItemAtIndex(2);
String bomb_time_status = splitter->getItemAtIndex(3);
String food_time_status = splitter->getItemAtIndex(4);
String feeded_times = splitter->getItemAtIndex(5);
From the Web App point of view, I get the LDR readed intensity of light to store in the log file together with log time, number of step motor turns, bomb time status, food time status and the number of food feeded times.
@app.route('/get_resume', methods=['GET', 'POST'])
def get_resume():
if request.args.get('ldr'):
ldr = request.args.get('ldr')
numero_voltas = settings.numero_voltas
today = datetime.datetime.now()
log_time = datetime.datetime.strftime(today, '%Y-%m-%d_%H:%M:%S')
food_time_status, start_date, end_date, now, food_time_count = check_food_time_func()
# print(food_time_status, start_date, end_date, now, food_time_count)
feeded_times = todays_food_func()
bomb_time_status, hour_now = get_bomb_time_func()
to_file = log_time + ',' + str(ldr) + ',' + str(numero_voltas) + ',' + str(bomb_time_status) + ',' + str(food_time_status) + ',' + str(feeded_times)
if bomb_time_status == 'yes':
with open('static/log.csv', 'a') as f:
f.write(to_file+'\n')
return jsonify(status=to_file)
return jsonify(status='failed')
The food time status is handled by another function called check_food_time_func. This function basicaly read the food log to check how many times the fishes were feeded at this day and check the interval I defined in start_hour and end_hour.
def check_food_time_func():
df = pd.read_csv('static/dispenser.csv')
now = datetime.datetime.now()
date, time = get_today()
start_hour = ['06', '10', '14', '18']
end_hour = ['07', '11', '15', '19']
count = len(list(df.loc[df['date'] == date].date))
for i in range(4):
start_date = date + ' ' + start_hour[i] + ':00:00'
end_date = date + ' ' + end_hour[i] + ':00:00'
# print(start_date, now, end_date)
start = datetime.datetime.strptime(start_date, '%Y-%m-%d %H:%M:%S')
end = datetime.datetime.strptime(end_date, '%Y-%m-%d %H:%M:%S')
if now > start and now < end and count <= i:
return 'yes', start_date, end_date, now, count
return 'no', start_date, end_date, now, count
The Food dispenser was a particular project too. First I tried the cheaper version building a helicoidal screw with electrical wire, which worked well for extruded type of food but not for flakes. The second attempt was a hand made helicoidal screw using pieces of washes put together with a electric soldering iron which doesn't worked well. The third attempt was a 16mm Wood screw that I cutted to fit my needs. That doesn't worked well with flakes too. Note, I tried those types of screw only with 2 types of motors, a Step Motor and a 3V DC Motor. I didn't want try another types of motors and using just what I already have.
The pictures bellow is showing the Sketchup 3D design I made to help in the process. And after that the pictures I took from the result.
After been exasperated with the helicoidal screw, in the version 2, I decided leave this option and try a simpler solution. I attach the food recipient to the dc motor with a hole in it. That solution worked weel and was stable but the food amount dispended to the fishes was difficult to measure. I attribute this to the 3 main reasons:
Here you can see very clearly the simplicity of the hardware. The Nodemcu, relay driver and the PWM to the motor. It was important to use the PWM because we can choose the velocity of the motor keeping the motor torque.
To make sure the number of motor's turns I implemented a switch attached on the other side of the motor axi, as you can see in the picture bellow.
In this version I tried a different approach:
Here I am using a Arduino to read sensors and switch the light, bomb and others devices I want in the future, led indicators and Step motor control. The Nodemcu I kept to manage the time food and bomb and light time. The communicattion between Nodemcu and Arduino was made via Serial port. The leds have the purpose of indicate how many times the fishes were feeded. The others functions are the same from the older versions:
In this version I could fix many points, such as:
Looks very ugly I know, but this is easy and fast way to get the final version, believe me.
The food dispenser was based on the comercial Food dispenser automation available in the market (see picture bellow).
Now lets talk about the new code implementations. The Nodemcu have a different behavior with the delay() function. When the loop stop in some point for much time the Nodemcu reset the device. Instead using the delay() function I used the following approach:
const long interval = 60000;
long previousMillis = 0;
void setup(){
// your configuration
}
void loop(){
long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
// run the code
}
Basically speaking, we set a interval time, when the difference between the current time is greater than the previous time the Micro-controller runs the code. It works like a charm.
In the Version 4 I decided keep the system off-line and working the code to do the job nicely. Basically talking we have the following steps:
This version is working very well. It is reliable, consistent and the fishes are happy as well. Could not be the best option for places with problems on Power supply, because this approach don't have memory. Once the Power supply is turned OFF the interval counting is lost.
To have a good turn ON/OFF time I have been monitoring the LDR value with the Arduino IDE Serial monitor in the morning (6 AM) and in the evening (7 PM). Doing this I could set a properly value to turn ON/OFF the filter and light as I wished and it is working with a few minutes of difference ( around 5 mins ). Of course this approach will depends on your location in the Globe :).
1. Import libraries
2. Variable and constant declaration
3. Setup
- PIN IN/OUT attribution
- Turn ON/OFF Filter and Light (LDR value dependent)
4. Loop
- reset check and food current time
- read manual feed button
- check time
- check LDR
- check status day/night
You can download the code here
In this picture you can see each part of the circuit.
For this version I bought a RTC module to fix the time better and to try the module for the first time. The RTClib does a real good job and make the code very easy to implement. First you need to set up the time and as the module has a battery to keep the memory ON, we do not have the problem we had in the previous version, when the Power supply shutdown cause lost of tracking time. The light and filter will turn ON/OFF the time you choose and your fishes will be happy to eat every day at the right time.
Bellow you can check some piece of code to make the reading less tedious.
Only you need to do is set the time calling the rtc.adjust() function with the time you want. After uploading the code you need to comment this line and upload the code again, of course :).
void setup(){
Wire.begin();
rtc.adjust(DateTime(2020, 3, 10, 14, 12, 30));
Serial.begin(9600);
}
After that you can get the date and time by just calling the rtc function as bellow.
void loop(){
// get the time
DateTime rtctime = rtc.now();
// You can access the values calling the related function as you can see b
hour = rtctime.hour();
minute = rtctime.minute();
second = rtctime.second();
year = rtctime.year();
month = rtctime.month();
day = rtctime.day();
}
You can check a more RTC lib fuctions examples here: https://github.com/adafruit/RTClib/tree/master/examples/ds1307
For this version I decided make the aquarium and Control Box a different system in order to facilitate the Aquarium maintenance.
Another advantage to this approach is portability as I can change the Aquarium many times I want because the size of the Aquarium don't interfers in the Control Box.
As you can see in the pictures, I didn't buy the temperature sensor and the heater yet, and also I am using a home made relay setup instead a arduino module. Just beacuse I had the components here and I wanted to keep this project as cheaper as possible.
Here you can find the link for almost all the materials I have used in this project. You have an international supplier (Amazon) and 2 Brazillian suppliers ( Filipeflop and Bau da Eletronica). I don't have any financial relationship with the mentioned shops, I just wanted to show where you can find these hardwares.
Product name | Amazon | Filipeflop | Bau da Eletronica |
---|---|---|---|
Arduino UNO | link | link | link |
RTC DS1307 | link | link | link |
Relay 4 channel | link | link | link |
Step motor 28BYJ-48/ULN2003 | link | link | link |
Arduino 9V power supply (comes with Arduino) | link | link | link |
5V/2A power supply | link | link | link |
wires/jumpers | link | link | link |
barrel connector | link | link | - |
3 terminal switches | link | link | link |
P2 connector male | link | link | link |
P2 connector female | link | link | link |
© Copyright 2019 marumaker.com