5. Input & Output device¶
Throughout the week we experimented with input and output devices paired them with microcontrollers using both Thonny and Arduino IDE to program and code.
The common theme with both languages C++ and Micropython was that we have to let the device know what is the inputs and the outputs in relation to its pins so it knows what information to take and how to react based on the conditions given to it.
RGB lights shifting using Thonny¶
it is not a perfect smooth color shift but it has a smooth transition partially and it is mostly because of the constant value difference that was added to the green and blue value that you can see in the code
The code¶
import machine import time
# Define RGB LED pins and PWM frequencies
RED_PIN = 12
GREEN_PIN = 13
BLUE_PIN = 14
PWM_FREQ = 1000
# Initialize PWM objects for each color
red = machine.PWM(machine.Pin(RED_PIN), freq=PWM_FREQ)
green = machine.PWM(machine.Pin(GREEN_PIN), freq=PWM_FREQ)
blue = machine.PWM(machine.Pin(BLUE_PIN), freq=PWM_FREQ)
# Function to shift colors automatically
def shift_colors():
for i in range(1024): # Duty cycle range from 0 to 1023
red.duty(i)
green.duty(1023 - i) # Inverse of red
blue.duty((i + 512) % 1024) # Shift blue by 512
time.sleep(0.01) # Adjust delay for speed of color shifting
# Call the function to start color shifting
while True:
shift_colors()
## RGB lights shifting using Arduino IDE
The code¶
const int redPin = 9;
const int greenPin = 10;
const int bluePin = 11;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
void loop() {
// Change the color to red
setColor(255, 0, 0);
delay(1000); // Delay for 1 second
// Change the color to green
setColor(0, 255, 0);
delay(1000); // Delay for 1 second
// Change the color to blue
setColor(0, 0, 255);
delay(1000); // Delay for 1 second
}
void setColor(int redValue, int greenValue, int blueValue) {
analogWrite(redPin, redValue);
analogWrite(greenPin, greenValue);
analogWrite(bluePin, blueValue);
}
Three speed fan control with a button¶
I faced an issue with the code of the 3 speed fan control as you see in the video the speed changes twice with one press of the button as the press and me removing my finger is being read as a signal so two speeds change at the same time
The code¶
I did not fully understand the issue of the button input and why is it happening but i solved it in the updated code by repeating each speed twice so when the speed switches twice I can still get my desired speed.
import machine
import time
# Define fan pin for PWM control
FAN_PIN = 26
PWM_FREQ = 1000
# Define button pin
BUTTON_PIN = 27
# Initialize PWM object for the fan
fan_pwm = machine.PWM(machine.Pin(FAN_PIN), freq=PWM_FREQ, duty=0)
# Initialize button object
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
# Fan speed levels (0-1023)
fan_speeds = [0, 0, 512, 512, 768, 768, 1023, 1023]
current_speed = 0
# Function to set fan speed
def set_fan_speed(speed):
fan_pwm.duty(speed)
# Function to handle button press
def button_press(pin):
global current_speed
current_speed = (current_speed + 1 ) % len(fan_speeds)
set_fan_speed(fan_speeds[current_speed])
# Attach interrupt to the button press
button.irq(trigger=machine.Pin.IRQ_FALLING, handler=button_press)
# Main loop
while True:
time.sleep(0.1) # Add a small delay to reduce CPU usage
The accelerometer results¶
The code¶
#include "I2Cdev.h"
#include "MPU6050.h"
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high
int16_t ax, ay, az;
int16_t gx, gy, gz;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO
// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO
#define LED_PIN 13
bool blinkState = false;
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(38400);
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
// use the code below to change accel/gyro offset values
/*
Serial.println("Updating internal sensor offsets...");
// -76 -2359 1688 0 0 0
Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
Serial.print("\n");
accelgyro.setXGyroOffset(220);
accelgyro.setYGyroOffset(76);
accelgyro.setZGyroOffset(-85);
Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
Serial.print("\n");
*/
// configure Arduino LED pin for output
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
#ifdef OUTPUT_READABLE_ACCELGYRO
// display tab-separated accel/gyro x/y/z values
Serial.print("a/g:\t");
Serial.print(ax); Serial.print("\t");
Serial.print(ay); Serial.print("\t");
Serial.print(az); Serial.print("\t");
Serial.print(gx); Serial.print("\t");
Serial.print(gy); Serial.print("\t");
Serial.println(gz);
#endif
#ifdef OUTPUT_BINARY_ACCELGYRO
Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
#endif
// blink LED to indicate activity
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
}
the Buzzer¶
me and my friend Faisal experimented with the buzzer and using the help of AI tools we were able to have the twinkle twinkle song to play
The code¶
import machine
import time
# Define speaker pin
SPEAKER_PIN = 26
# Define frequencies for the notes in the melody
# Note: Frequencies are in Hertz
C = 262
D = 294
E = 330
F = 349
G = 392
A = 440
B = 494
# Define the "Twinkle, Twinkle, Little Star" melody with note durations
twinkle_melody = [
(C, 0.5), (C, 0.5), (G, 0.5), (G, 0.5),
(A, 0.5), (A, 0.5), (G, 1),
(F, 0.5), (F, 0.5), (E, 0.5), (E, 0.5),
(D, 0.5), (D, 0.5), (C, 1),
(G, 0.5), (G, 0.5), (F, 0.5), (F, 0.5),
(E, 0.5), (E, 0.5), (D, 1),
(G, 0.5), (G, 0.5), (F, 0.5), (F, 0.5),
(E, 0.5), (E, 0.5), (D, 1),
(C, 0.5), (C, 0.5), (G, 0.5), (G, 0.5),
(A, 0.5), (A, 0.5), (G, 1)
]
# Initialize PWM object for the speaker
speaker_pwm = machine.PWM(machine.Pin(SPEAKER_PIN), freq=0, duty=512)
# Function to play a note
def play_note(note, duration):
if note == 0: # Check for rest
time.sleep(duration) # Pause for rest duration
else:
speaker_pwm.freq(note)
time.sleep(duration)
# Function to play the melody
def play_twinkle_twinkle():
for note, duration in twinkle_melody:
play_note(note, duration)
# Play the "Twinkle, Twinkle, Little Star" melody
play_twinkle_twinkle()
Overall¶
Through this week we were able to experiment with different input/output devices which was light and easy and at the same time very fun to do. To conclude this week I would like to mention what have been learned dealing with these different devices:
1- We learned how to further use MicroPython and C++ but using the actual devices rather than simple LED codes from the previous week.
2-I learned about libraries that might be provided by the manufacturers of the devices to be able to test and use the input/output devices.
3-I learned how to test sensors based on their functionality.
4-I learned that some sensors have different measuring methods and the different ways they can communicate in with the micro controller(Some sensors use digital pins giving a value of 1 or 0 while other sensors measure things continuously with varying values which use analogue pins or the SCL and SDA pins which actually correlates to the properties of the sensor itself).
5-I learned how to integrate multiple input and output devices in a system to have a functionality.
6-I learned some debugging processes that could be applied when having issues with the code (such as digital printing a line to know where the code is stopping).
This week was extremely valuable to me as I learned a lot and I was able to experiment with something I was curious about. Although, I found it difficult when dealing with code problems as I do not have a background in coding so I had to ask for help from Haitham and Duaa which was very very helpful (definitely recommend).