Christmas Smart Home

Our goal with this project was to build off of what we learned in class and incorporate previous Arduino experience to create our own implementation of a system that is found in the real world. From this, we landed on creating our own version of a modular Smart Home with a Christmas themed twist. This smart home uses the temperature captured by the Atmega328P Explained Mini board connected to a thermistor, similar to the set up from lab 3, to determine when it is truly time to get in the Christmas spirit. Once the temperature registered by the Atmega328P Explained Mini board gets above 45 degrees Fahrenheit, it uses the serial peripheral interface to communicate to the Arduino Nano. Once the Arduino Nano receives the signal from the Atmega328P Explained Mini board, the Arduino Nano turns on the LED fireplace. In addition to the temperature-responsive system, we controlled LED strips from the Arduino Nano using pulse wave modulation to create a Christmas Tree and Christmas Wreath with a twinkling light effect. An OLED was added to display system information. Finally, to have an excuse to get to work with the servo motor discussed in class, we connected a servo to the Arduino Nano alongside a potentiometer such that we could open and close the door with a lever.

Traffic Control System – Schematic

7-Segment Common Anode Displays and 7447 Decoders were used for the crosswalk countdown sign for this project. 7-Segment display made up of 7 individual red LED (Light Emitting Diode). Each segment was assigned from A to G. The A segment located up top horizontal, the B segment is to the right vertical, CDEF followed in a clockwise direction, and G segment is horizontal located in the middle. All Common Anode Display of LED’s are joined together to logic “1” and each of the individual segments light up by connecting individual cathode terminal to a “0” or “LOW” signal. The image below illustrates the 74LS47 decoder connection with the common anode 7segment display.

Servo Motors were used to imitate the railroad gate in the railroad subsystem. Servo motor is a device in which it can rotate and change the motion or direction of attached devices. Servo motors can operate by sending pulse width modulation (PWM) through the control wire. Via the code, you start by setting the compare match A and then the clock prescaler values to /64. Then calculating for the frequency needed by the servo motors (there datasheets). You can find the ICR1 necessary value. Which is connected to the OCR1A/PB1 slot on the Atmega328PBxMINI board. You can then produce a PWM type signal that can be adjusted by Subtracting from that ICR1 value. By experimenting with the values. You are able to configure the angles of the servo, this is all depending on it’s possible angles.

IR Sensors are a simple digital sensor that has two components. The first component is called the Transmitter/Emitter. This transmitter device emits an IR beam. The presence of that IR beam is then read by the second component; the receiver/collector. If this receiver cannot see the IR beam, a low bit is returned from the sensor, else a high bit is returned if the beam is in tact.

The Traffic Lights are a series of green, red and yellow LEDS attached to a backboard. They require four wires, one for each LED and one for ground. Since all the LEDs share the same ground it is fairly easy to wire and test these.

The buttons are a small circuit attached to ground and the board. The board could tell when even a ground signal was detected because an internal pull up resistor was set up along with configuring the PINC ports to Inputs for the software to then read from.

Piano Glove Code

Here are a few code snippets from Team 10. This code deals with the creation of the note C in Assembly in PCIN_H. Several time compares are also used to toggle between the different notes.

Below shows PCINT1_H which is a pin change interrupt used to toggle each note to turn on and off.

Below is a TIME2_COMPA: Used to switch between different notes using different frequencies on the respective finger on the glove.

Fire Alarm – Big Picture

We wanted to do a project that incorporated everything that we learned in the class. The goal was to design a project that was cheap, yet practical. We ended up deciding to make a fire alarm detection system. Alongside our ATmega328P, we used a Melexis Contact-less Infrared Sensor (MLX90614), AST-3208MR-R buzzer, and LED to create a circuit that alarms the user when there is a fire nearby. The buzzer needs a sine wave to work, so we took what we learned about PWM to simulate a sine wave for this component to function. We also applied other concepts like I2C to communicate between our micro controller and Infrared Sensor. By adjusting the top value in ICR1 we could adjust the frequency and duty cycle, allowing us to change the pitch and volume of our alarm.

Fire Alarm Hardware

Using knowledge gained from the software and corresponding hardware used in labs 3 and 4 as starting points, we implemented and amplified a PWM signal as the main driving source for an audible and visual fire alarm. This amplified signal came from the TIP120 transistor. The base pin was connected to GPIO pin PB1. The emitter pin of the transistor was simply connected to ground. To amplify the signal given from PB1, the collector pin acted as the ground source for both the Piezzo buzzer and the LED. These two components, the buzzer and LED, were connected in parallel, with both positive leads connected to a 5V source provided by the ATMega328P. Being connected in parallel allowed the alarm and LED to correspond while pulsing, such as when a higher pitch provided by the speaker was present, the LED would shine brighter.

As seen in the video, as the pitch provided to the speaker increases, the LED shines slightly brighter. As the speaker's pitch decreases, the LED gets dimmer.

The MLX90614 temperature sensor was the bread and butter of the fire alarm. It acted as a switch to drive current to the buzzer and LED. Once the object temperature of the IR sensor surpassed a set threshold provided in the code, the sensor drove a signal to the ATMega328P, which then told the MCU to send a PWM output to the alarm system. Two GPIO pins on the ATMega328P were connected to the SCL and SDA pins on the sensor. These two pins were also connected to the 5V source on the breadboard through 10kOhm resistors. The other two pins of the sensor were connected to voltage and ground.

Traffic Control System – Big Picture

Traffic Intersection

Traffic controls are a part of everyone’s daily life. To understand the application of the traffic control system, this laboratory is dedicated to a simulation of a three-way intersection traffic system that consists of three subsystems: traffic lights function, crosswalk function, and railroad gate function. The system is powered by two ATMega328P microcontrollers using Atmel Studio 7 software application and C programming language. The hardware for the project includes 6 traffic light LEDs, 6 anode 7-segment displays for the crosswalk, 4 red LEDs and 2 servo motors for the railroad gate controls system. The circuit is powered with 21 of 470Ω resistors, 2 of 74LS47 decoders. There were three main phases of this project: the project development phase, then the hardware execution phase, and the software debugging phase. During the project development phase, parts and tools were purchased. Moreover, the basic foundation of the project was built such as traffic light poles with wooden sticks, train tracks with popsicle sticks, and street surfaces with construction paper. After that, hardware parts were installed and all parts were soldered in the ATMega328P microcontroller during the hardware execution phase. Finally was the software debugging phase where C codes were tested timed for the perfect execution.

Presentation Video – Traffic Controls in action!

The Traffic Intersection was constructed on a 20in by 30in black foam board. The chosen intersection design was a T-Junction, where a main road is intersected by a side road (Similar to the intersection outside The William Speed Building). Green construction paper was used as grass, and to create the shapes of the road. Gray duct tape lines the road to mimic sidewalks while yellow duct tape dots the center of each road. A few traffic arrows and signs were printed out to add to the aesthetic. The traffic poles were made of wooden sticks covered in shiny metallic tape. The traffic lights were mounted to popsicle sticks protruding off each pole. Also on the poles were the 7-segment displays. These displays would countdown so pedestrians would know how long they have to cross, similar to a real intersection. The buttons couldn’t be mounted to the poles since they required to be pressed, and we wanted to minimize the forces on the poles to prevent them from being torn out. So the buttons were placed on the ground near each pole. The IR Sensors are placed on either side of each road to act as a trigger, whenever a car passes by. In real life induction loops are used to detect when a car has come to an intersection, but in this mock intersection, IR Sensors are used.

The train tracks were made with small popsicle sticks, and sat on top of a strip of brown construction paper. The servo motors were covered in shiny metallic tape and the traffic arm is a large popsicle stick covered in red and white construction paper. The train LED indicator poles are made out of small popsicle sticks wrapped in duct tape with the LED stems just wrapped around the t-section. Some railroad crossing signs were printed out to add to the aesthetic. All the wires were ran underneath the board to prevent cluttering the surface and to maintain the illusion of simplicity. The two ATmega328P Microcontrollers and the three breadboards were placed on the southeast corner of the intersection.

More Images

Piano Glove Big Picture

We are Team 10. We wanted to do something fun and interactive. Our team enjoys music so we wanted to create something that reflected our interests. Introducing the Piano Glove–a musical device used with AtMega32p to play a C scale and chords so you can show off your piano skills to your peers! This objective of this project was to build a glove that would play an individual tone for each finger. The first thing done was to brainstorm ideas on how this could be made to work. This project was made to use switches to control a signal to the Atmega328p. The code would use interrupts to handle when the value was high and low to start or stop the addition of waves coming out of the Atmega328p. Originally pulse width modulation was gonna be used with a low pass filter to control the amplitude and only one wire was gonna be used as an output. After receiving the parts we found that the switches were too small and had decided to move to a conductive pad and wires. Another problem was that using pulse width modulation (PWM) was going to produce too low frequencies than what was wanted. Instead, each note would have its own output and be combined with an adding circuit. The final issue was that we could not get the amplification circuit to work. Atmel Studio 7 was used to program the Atmega328p. An oscilloscope was used to check the frequency of notes and the combination of notes. There could have been improvements on the wiring and the design by changing the lengths or location of wires,  the switches could be changed with a capacitance circuit and the clock speed could possibly be adjusted to eventually use PWM. there are MCU’s that are made to be used for sound construction, however, this would change the hardware and the project as a whole. A headphone jack could be added to be able to amplify the sound. @Fall2019 @Team10 @ProjectIdeas @PianoGlove

Ping Pong Ball Level

  uint8_t range = vl.readRange();
  error = goal - range;
  sum_error = sum_error + error*2;
  D_error = error - last_error;
  servo = servo_setpoint - balance.PID_P(Kp, error) - balance.PID_I(Ki, sum_error) - balance.PID_D(Kd, D_error);
  last_error = error;
  if (servo > 110)servo = 110;
  if (servo < 53)servo = 50;
  myservo.write(servo);

In the setup block, the serial monitor was initialized for debugging purposes. Then the LCD, time-of-flight sensor, and servo modules were initialized. In the loop function, the first thing that happens is a reading from the distance sensor to get the current location of the ping pong ball. Then the PID error calculations are done before passing them into the library to return the servo output values. A delay is put in place to pause the program after each servo write to keep the PID control loop in sync with the output. The figure shows the state of the system at rest and with an impulse where the ball is struck to see the response. Two spikes at about one third and two-thirds of the way across the graph represent these impulses in the blue line. The red graph represents the servo’s response to the impulse to correct the track and get the ball back into the middle.

Fire Alarm – Code

The fire alarm was coded in C on the ATMega328P using Atmel Studio 7.0. An assembly file was also written alongside the C file for USART implementation to be able to communicate with a serial terminal program for testing and debugging purposes. Our code has 3 important logical sections to integrate each part of the fire alarm into an embedded audio/visual system.

This compare handler utilizes PWM mode 14 so that we can vary both the top value through ICR1, and the duty cycle through OCR1A. The input compare register acts as our top value and is decremented until the value is 1 more than the output compare register. This ensures that we never end up with a compare value less than the top value, which would lead to an indefinite pause as a compare match would never be reached. Varying the top value is important as a fixed top value would create a breathing LED but would limit the buzzer to a single pitch.

ISR(TIMER1_COMPA_vect)						
{
	if(direction == 0){
		if (OCR1A < (ICR1-1)){
			ICR1--;
			OCR1A++;
		}
		else{
			direction = 1;
			OCR1A--;
			ICR1++;
		}
	}
	else{
		if (OCR1A &gt; 1){
			OCR1A--;
			ICR1++;
		}
		else{
			direction = 0;
			ICR1--;
			OCR1A++;
		}
	}
}

Our MLX function is responsible for retrieving the object temperature read by the IR sensor. Each of the individual functions are combined here to make the source code easier to follow. Between each request sent to the sensor, the function performs a wait check to ensure integrity during the data transfer process. The first block is the write request responsible for specifying an address in RAM for the sensor to store the object temperature to. The second and third block retrieve the low and high bytes of the output respectively. This system takes full advantage of the sensor’s I2C capabilities so that we can continuously read and write data at a high speed. Finally, the MLX function concatenates the the output and converts it into a readable temperature.

void MLX(void)
{
	int high, low;

	i2cSendStart();
	i2cWaitForComplete();
	i2cSendByte(0x00);    //SLA+W
	i2cWaitForComplete();
	i2cSendByte(0x07);    //Get object temp
	i2cWaitForComplete();
	i2cSendStop();
	
	i2cSendStart();
	i2cWaitForComplete();
	i2cSendByte(0x01);   //SLA+R
	i2cWaitForComplete();
	i2cReceiveByte(true);
	i2cWaitForComplete();
	low = i2cGetReceivedByte();	//low byte
	i2cWaitForComplete();

	i2cReceiveByte(true);
	i2cWaitForComplete();
	high = i2cGetReceivedByte();	//high byte
	i2cWaitForComplete();
	i2c_receive_pec() ;
	i2cSendStop();
	
	Toreg = (high << 8)|low; //concatenate MSB and LSB
	Tf = (((long)Toreg * (3.6)) - 45967)/100; //temp F
}

The sensor, buzzer, and LED are integrated here. This loop is implemented in the main section of the code. During the continuous loop, the temperature is compared to a threshold. When the temperature is less than this threshold, the alarm is turned off by disabling the ATMega328P Timer1, and resetting the compare registers. If these registers are not reset, the direction, frequency, and duty cycle would be random upon reactivation and would result in an inconsistent system. Once the continuous temperature reading rises above the threshold, the alarm is enabled. Each if statement checks to see the current state of the alarm so that no unnecessary resets are done.

sei();
while (1){
		MLX();
		floatToString(Tf,temp,2);
		UART_Puts("\r\nTemp: ");
		UART_Puts(temp);
		if(Tf < tempComp){
			//turn off alarm
			if(TCCR1B != 0){
				TCCR1B = 0;
				TCNT1 = 0;
				ICR1 = top;
				OCR1A = 0;
				direction = 0;
			}
		}
		else{	
			//enable alarm
			if(TCCR1B == 0){
				ICR1 = top;
				OCR1A = 0;
				TCNT1 = 0;
				TCCR1B = 0b00011011;
			}	
		}

	}