A Fan control system with ATmega2560 Microcontroller

The following project was developed during a class taken at Federal University of Rio Grande do Norte with professor Marcelo. The group was composed by GiovannaJoãoRaí and me.

The group goal was to implement a drying grain system. The process of drying should start with the press of a button, after that, a fan speed is controlled based on a “dry curve” and the reading of a luminosity and temperature sensor. With 3 minutes the routine is finished, and the machine should wait for another button press to start the system again.


The hardware of the control system consists of:

  • An ATmega2560 Microcontroller
  • An LDR to sense the luminosity
  • An NTC sensor for the temperature
  • A Push-Button to start the system
  • LEDs for behavior visualization
  • A “4N25” Photocoupler to protect the Microcontroller from the load
  • An NPN transistor with a diode for circuit protection
  • Power supply to the Fan
  • Some resistors

The last picture represents the components, an Arduino Mega board is used to facilitate communication with the microprocessor, the DC motor illustrates the fan. Since the LDR and NTC sensors are a variable resistance for the desired domain, a voltage divider is applied to convert the input voltage to a measured voltage. An operational range should be specified in this type of configuration, in the example of the NTC temperature sensor, the fixed resistor was chosen based on its measured resistance at the ambient temperature which, for 25 °C is approximately 50Ω.


Continue reading

Easily Using SWI-Prolog within Matlab

This post intends to show how to interact with SWI-Prolog codes inside MatLab.

The following code is an arbitrary example of a special system, which covers different situations for “control” based on various inputs.

:- dynamic upOn/0, upOff/0.


getOn(sensor,Value) :- Value < 0.5.
getOff(sensor,Value) :- Value > 0.5. 

setOn(valve,Value) :- Value is 1.0.
setOff(valve,Value) :- Value is 0.0.

control(V_in,V_out,S0,S1,S2,SW) :- getOff(sensor,SW),getOff(sensor,S0),getOff(sensor,S1),getOff(sensor,S2),upOff,setOff(valve,V_in),setOff(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOff(sensor,S0),getOff(sensor,S1),getOff(sensor,S2),upOff,setOn(valve,V_in),setOff(valve,V_out),retract(upOff),asserta(upOn).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOn(sensor,S0),getOff(sensor,S1),getOff(sensor,S2),upOn,setOn(valve,V_in),setOff(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOff(sensor,S2),upOn,setOn(valve,V_in),setOff(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOn(sensor,S2),upOn,setOff(valve,V_in),setOn(valve,V_out),retract(upOn),asserta(upOff).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOn(sensor,S2),upOff,setOff(valve,V_in),setOn(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOff(sensor,S2),upOff,setOff(valve,V_in),setOn(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOn(sensor,SW),getOn(sensor,S0),getOff(sensor,S1),getOff(sensor,S2),upOff,setOn(valve,V_in),setOff(valve,V_out),retract(upOff),asserta(upOn).
control(V_in,V_out,S0,S1,S2,SW) :- getOff(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOn(sensor,S2),setOff(valve,V_in),setOn(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOff(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOff(sensor,S2),upOff,setOff(valve,V_in),setOn(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOff(sensor,SW),getOn(sensor,S0),getOn(sensor,S1),getOff(sensor,S2),upOn,setOff(valve,V_in),setOn(valve,V_out),retract(upOn),asserta(upOff).
control(V_in,V_out,S0,S1,S2,SW) :- getOff(sensor,SW),getOn(sensor,S0),getOff(sensor,S1),getOff(sensor,S2),upOff,setOff(valve,V_in),setOn(valve,V_out).
control(V_in,V_out,S0,S1,S2,SW) :- getOff(sensor,SW),getOn(sensor,S0),getOff(sensor,S1),getOff(sensor,S2),upOn,setOff(valve,V_in),setOn(valve,V_out),retract(upOn),asserta(upOff).

The above code can be called by another Prolog script as follows:

#!/usr/bin/env swipl

:- initialization main. 

main:-  current_prolog_flag(argv,Argv),
        nth0(0, Argv, A), % get first argument
		nth0(1, Argv, B), % get second argument
		nth0(2, Argv, C), % get third argument
		nth0(3, Argv, D), % get fourth argument
		format("~w ~w ~w ~w \n",[A,B,C,D]), % Print inputs
        consult('example1Prolog'), % Load main Prolog code
		atom_number(A,E), % Transform inputs into Prolog integers
		control(X,Y,E,F,G,H), % Query control function with inputs
		format("X= ~w Y= ~w \n",[X,Y]),	% Prints output variables
		halt. % Finishes execution

The script is executed with the bash shell command:

swipl -s plscript.pl 1 1 1 1

Where the last 4 numbers stand for the Prolog code inputs. The following output with the above command is:

1 1 1 1
X= 0.0 Y= 1.0

Most of the work is already done! (WOW). The last step is executing the same bash command within Matlab using the “system” function:

[status,term_out] = system('swipl -s plscript.pl 1 1 1 1')

“term_out” variable will hold the script output for the inputs given. The following picture shows the previous call output on the main console with the described method.


Note: It is important to check if a set of inputs will return valid outputs for the system (if they are covered). Also, make sure to test if the script is reaching the last line “halt.”, otherwise the SWI-Prolog will open without closing and the Matlab will wait until the application finishes (never) and crash.

The following Prolog command is helpful if the developed Prolog code depends on dynamic variables like the one shown in this tutorial:


The problem is that the saved data can not be loaded into a running environment, making this post approach not to work for dynamic variables (for now).

Files can be accessed at: