Interfacing Input and Output Devices
Introduction
Arduino Programming is an essential tool we will be making use of when making our chemical product. In the past few weeks, we have taken a look at how to program different functions on both the Maker Uno board and external input and output devices. Below are some of them that we had assembled both with our physical Maker Uno board and on Autodesk TinkerCAD.
In the following examples of interfacing, a prerequisite is that the 5V supply of the Maker Uno board is connected to the positive side rail of the breadboard, while the ground is connected to the negative side rail. These the positive and negative rails serve as the connection points whenever I say I connected the circuit to 5V or ground respectively.
Here's how I interfaced two analogue inputs and two output devices.
Interfacing a Potentiometer
A potentiometer, otherwise known as a variable resistor, is a device that has a knob that changes the resistance of the circuit when it is turned. I interfaced the potentiometer by placing it on the breadboard and having all three of its pins on three different rows (as each row would be "connected" to one another). I connected the leftmost pin to the 5V supply and the rightmost pin to ground using DuPont wires. I then connected the middle pin to the port A0 on the Maker Uno board. This allows the board to read the voltage output that would change depending on the position on the knob, as the resistance of the circuit would vary depending on it.
In order to see the change in resistance, I programmed the Maker Uno board to show a numerical value of the voltage of the circuit that changes when the knob is turned using the following code:
int sensorValue = 0; // this sets up a variable sensorValue that will be shown in the serial monitor once the code is ran
void setup()
{
pinMode(A0, INPUT); // sets analogue pin A0 as the input
pinMode(LED_BUILTIN, OUTPUT); // sets the default built-in LED, which is on pin 13, to be the output
Serial.begin(9600);
}
void loop()
{
Serial.println(sensorValue); // shows the voltage output values in the serial monitor
sensorValue = analogRead(A0);
digitalWrite(LED_BUILTIN, HIGH);
delay(sensorValue);
digitalWrite(LED_BUILTIN, LOW);
delay(sensorValue);
}
Here is the TinkerCAD simulation for the potentiometer:
And here is a video of the potentiometer in action:
Interfacing a Light-Dependent Resistor
A light-dependent resistor (LDR) is another type of variable resistor and input device. As the name implies, the resistance through the resistor varies depending on the intensity of light that is incident on it. Typical LDRs have a resistance that increases with the intensity of the light, or vice versa.
I interfaced the LDR by connecting one end of the LDR to the 5V supply, put a resistor in series with the LDR and connected the free end of the resistor to ground, both using DuPont wires. In the same row where the LDR and resistor are, I connected the row to the pin A0 on the Maker Uno board using another DuPont wire.
In the circuit I have assembled, I also made the Maker Uno board show a numerical value of the voltage of the circuit. I took a video of it in action as well, and in it, you can see that removing my hand between the LDR and my computer monitor made the values on the serial monitor increase, and the same happened when I turned on my lamp. This was because the voltage of the circuit increased as the resistance of the LDR decreased when the light intensity was increased. I wrote the following code for the LDR:
int light; // this gives an arbitrary integer value of the voltage through the LDR that changes depending on the light intensity
void setup() {
Serial.begin(9600);
}
void loop() {
light = analogRead(A0); // the value of the variable I set earlier quantifies the voltage through the LDR circuit
Serial.println(light);
delay(100); // this makes the microcontroller take a reading every 100 ms or 0.1s
}
Here is the TinkerCAD simulation for the LDR (though it does not work and hence why I supplemented a video below):
Currently in the works is a workaround for the LDR not working on TinkerCAD. I was thinking of interfacing and programming an LED beside the LDR that would blink every second or so and that would change the voltage reading of the LDR circuit.
Interfacing LEDs
Now we move onto output devices. The earlier two examples were input devices, where voltage of the circuit was recorded as an input by the Maker Uno board and were influenced by the two devices I interfaced. Now, the roles are reversed and it is the devices that I interfaced that will be affected by the Maker Uno board.
The first of two output devices we will take a look at are LED lights. In essence, they are diodes that change electrical energy into light energy when a current passes through them, hence the name Light Emitting Diode.
In terms of interfacing the LEDs, I placed them on the breadboard in such a way that the anode (positive terminal) and cathode (negative terminal) were in two different rows. I connected the cathode to a 10 kiloohm resistor with one for each LED to prevent the LEDs from blowing out. I connected the anode to the Maker Uno board's pin 13, 12 and 11 for the red, yellow and green LEDs respectively, each with its own colour-matching DuPont wire.
For this project, I made the LEDs light up first for one second, then blink twice quickly before moving on to the next LED. As an added challenge, I made it so that the lights only blinked when the on-board button is pressed. It took me a while to realise that the colours were actually the same as a stoplight and hence I didn't take this into account when coding the light sequence, and I hope no one will ever make me code an actual stoplight or chaos would ensue...
Regardless, here is the code I wrote to make the LEDs run the light-up sequence I described from earlier when the on-board button is pressed:
int blinkSpeed = 0; // this variable is the amount of time the LED stays on or off
int changeOver = 0; // this variable is the amount of time before the next colour LED does the light-up sequence
int onTime = 0; // this variable is the amount of time the LED stays on for the initial flash
int buttonState = 0; // this variable reads whether or not the on-board button is pressed or not
void setup()
{
pinMode(2, INPUT_PULLUP);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
}
void loop()
{
blinkSpeed = 250;
onTime = 1000;
changeOver = 500;
buttonState = digitalRead(2);
if (buttonState < HIGH) {
digitalWrite(13, HIGH); // when the button is pressed, the first LED which is red will do the light-up sequence of turning on for one second, quickly flashing twice and moving on to the next LED.
delay(onTime);
digitalWrite(13, LOW);
delay(blinkSpeed);
digitalWrite(13, HIGH);
delay(blinkSpeed);
digitalWrite(13, LOW);
delay(blinkSpeed);
digitalWrite(13, HIGH);
delay(blinkSpeed);
digitalWrite(13, LOW);
delay(changeOver);
digitalWrite(12, HIGH); // the next LED which is yellow will now do the same light-up sequence as the red LED
delay(onTime);
digitalWrite(12, LOW);
delay(blinkSpeed);
digitalWrite(12, HIGH);
delay(blinkSpeed);
digitalWrite(12, LOW);
delay(blinkSpeed);
digitalWrite(12, HIGH);
delay(blinkSpeed);
digitalWrite(12, LOW);
delay(changeOver);
digitalWrite(11, HIGH); // finally, the green LED will do the light-up sequence and the LEDs will remain off until the button is pressed again
delay(onTime);
digitalWrite(11, LOW);
delay(blinkSpeed);
digitalWrite(11, HIGH);
delay(blinkSpeed);
digitalWrite(11, LOW);
delay(blinkSpeed);
digitalWrite(11, HIGH);
delay(blinkSpeed);
digitalWrite(11, LOW);
delay(changeOver);
} else { // when the button is not pressed, the LEDs will all be off
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
}
}
A bit of a doozy in terms of the number of lines, innit? I think this code is perfectly fine since it is functional and works as intended, though I think it can be simplified using a for loop. It would condense the blink sequence for each LED into just one for all three. I would write it as for (int pin = 13; pin >= 11; pin -=1) {}, which would make the code run once for each pin, and I would replace the number in the digitalWrite lines with pin instead. This would make the code a lot shorter, and in my opinion, much neater.
Here is the TinkerCAD simulation for the Stoplight LEDs. I would like to point out that due to the lack of an on-board button on the Arduino board that we use in TinkerCAD, I had to program separate pushbutton on the breadboard. As such, the code is slightly different, since by default, when using the on-board button for our Maker Uno board, we have to make the mode of pin 2 as INPUT_PULLUP, but in TinkerCAD and the pushbutton, it is only a normal INPUT. These are just some minor differences to take note of between the actual, physical setup and the TinkerCAD simulation, though functionally, they work the same.
And here's a short video of the actual LED setup:
Interfacing a DC Motor
Lastly, we need to interface a DC motor. For this output device, I interfaced the DC motor by connecting the black terminal to pin 10 of the Maker Uno board, and the red terminal to the 5V supply. The connections can be reversed to change the direction of rotation of the motor.
I coded the following to make the DC motor turn whenever the on-board button is pressed:
int buttonState = 0; // this variable reads whether or not the on-board button is pressed or not
void setup()
{
pinMode(2, INPUT_PULLUP);
pinMode(10, OUTPUT);
}
void loop()
{
buttonState = digitalRead(2);
if (buttonState < HIGH) { // this is when the button is pressed, the signal to the motor will be high
digitalWrite(10, HIGH);
} else {
digitalWrite(10, LOW);
}
delay(10);
}
Here is the TinkerCAD simulation. Like with the Stoplight LEDs, the same differences apply in terms of having to add an external pushbutton.
Maybe we got lost in translation, maybe I asked for too much, but maybe the contacts of the DC motor wires were not long enough to reach the metal rails of the breadboard. Either way, I was not able to make the physical DC motor turn and we are not quite sure what the cause is. Our running theory is that the exposed part of the wire of the DC motor cannot reach the metal contacts in the breadboard and hence it would not run, our we have a faulty DC motor. We will investigate this in the near future and I will update the blog with a video once we resolve the issue.
Reflection
Right off the bat, I can say that Arduino programming was definitely not a walk in the park for me. As a few people would probably happily point out, I am not the best at logical thinking and having to put together code that not only has to make sense, be functional AND remember the syntax of C++ for the code was definitely a lot harder than I thought. Though given some time and probably some more practice in the coming weeks, I think I can definitely get the hang of it. I would definitely want to improve as much as I can, especially in terms of coding for the DC motor as we would need to use it for our final product, the egg boiler.
These few tasks on coding for input and output devices has definitely helped a lot as I was able to explore more about interfacing with the Maker Uno board. Knowing that they were not very far off from coding different functions within the board was very assuring and the learning curve was thankfully not as steep as expected, though it was not easy either as I previously mentioned. My confidence in coding and interfacing input and output devices has definitely gone leaps and bounds past where it was before we started and I hope to make good use of them in the next few months.
Comments
Post a Comment