CSC270 Team 5 project 2019
Stacy Falaleeva, Joce Kofke, and Jessie Wang
Contents
Sound-Activated Stopwatch
Introduction
For our project, we created a stopwatch activated by the sound of a clap. It starts, stops, and resets with each clap.
Implementation
Software
Languages
We used C on both the Arduino and the Raspberry Pi.
Libraries
- Arduino
- RaspberryPi
Hardware
- RaspberryPi 3
- Arduino Mega2560 : Manual
- LED Numeric Display, 4 Digit (BL-Q39X-42) : Manual
- Arduino KY-037 Sensitive Microphone Sensor Module : Manual
Plan
Process
DISCLAIMER: The code in this section is messy and undocumented. It was in-process code to help us form our finalized code, and is attached here to show the process and building blocks that make up the final result. The important sections were incorporated into our final code, and are explained there.
- 1. Sound Sensor
- We began by testing the usability of the sound sensor. We hooked it up to the Arduino and flashed an LED when a clap was registered. This also allowed us to adjust the sensitivity of the sound sensor. We ran into the problem of bouncing of the signal, which we fixed by simply adding a short delay.
- 2. Stopwatch
- We then moved on to programming the stopwatch on the Raspberry Pi, which displayed in the terminal. Despite initial trial and error, we eventually used a finite state machine to switch between the three states of running, stopped, and reset.
- 3. Display
- For the display, we used the Sevseg library. We confirmed that it was wired properly and would display a given number.
- 4. Combination
- This final step resulted in our final product. There were many, many issues with this step, especially with communication between the RPi and the Arduino, and the display not working properly because the refreshing of the display only occurred when the serial connection was available, but in the end we got to the final code.
Final Code
Arduino
/* Arduino Loop
* Joce Kofke, Stacy Falaleeva, Jessie Wang
* May 2019
*
* Displays data received from Raspberry Pi stopwatch.c
* on a 4 digit 7 segment LED display
*
*/
#include <SevSeg.h> // library for digit display
SevSeg sevseg;
int incomingByte = 0;
// setup code, runs once
void setup() {
Serial.begin(9600); // begins communication with the RPI at a baud rate of 9600 bps
// -- SevSeg setup START --
// mostly taken from reference
byte numDigits = 4;
byte digitPins[] = {10, 11, 12, 13};
byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};
bool resistorsOnSegments = true;
bool updateWithDelaysIn = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
// -- END --
}
// main code, runs repeatedly
void loop() {
sevseg.refreshDisplay(); // refreshes display constantly
if (Serial.available()){
incomingByte = Serial.read(); // reads the byte sent from RPI
Serial.println(incomingByte, DEC); // displays the data in the Serial Monitor
sevseg.setNumber(incomingByte); // sends the data to the display
}
}
RaspberryPi
/* Stopwatch
* May 2019
* Joce Kofke, Stacy Falaleeva, Jessie Wang
*
* Runs a stopwatch on the Raspberry Pi
* based on state determined by sound sensor
* and sends the value to the Arduino
*
* to run:
* gcc -o stopwatch stopwatch.c -lwiringpi
* ./stopwatch
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <wiringSerial.h>
int buttonpin = 1; // the pin of the sound sensor
int state = 0; // the current state of the stopwatch ( 0 = reset, 1 = start, 2 = stop )
int clap; // reads the sound sensor
int lastClap = 0; // stores what the previous reading of the sound sensor was
int lastSec = 0, currSec = 0; // keeps track of whether a second has passed
clock_t start, end; // monitors time elapsed through the processor
int serial_port; // the serial port for communication with the Arduino
char send[5]; // the byte sent to the Arduino
int idea; // keeps track of whether "0" has been sent to the Arduino on reset
// state 2 - stops the stopwatch
void stop(){
return;
}
// setup - runs once
void setup(){
wiringPiSetup();
pinMode(buttonpin, INPUT); // sets buttonpin to receive input from sound sensor
pullUpDnControl(buttonpin, PUD_UP);
serial_port = serialOpen("/dev/arduino", 9600); // opens serial connection with arduino, sets baud rate to 9600bps
}
// main code - runs repeatedly
void loop(){
clap = digitalRead(buttonpin); // reads value of sound sensor - 0 if silent, 1 if clap heard
// if the clap has finished
if (clap == LOW && lastClap == HIGH){
delay(250); // debouncing
state = (state + 1) % 3; // changes state
if (state == 1){ // if the new state is start state
start = clock(); // sets "start" to the current processor clock value
}
else if(state == 0){ // if the new state is the reset state
printf("READY\n"); // prints READY (debugging)
}
}
if (state == 1){ // if the state is currently 1
end = clock(); // sets "end" to the current processor clock value
currSec = ((int)(end-start))/CLOCKS_PER_SEC; // finds time elapsed and divides by the number of processor ticks
// per sec to get number of seconds elapsed
//only sends something to Arduino when second changes
if (lastSec != currSec){
printf("%d\n", currSec); // debugging
char c = (char) currSec; // changing currSec from int to char
printf("Sending this to Arduino: ", c, "\n"); // debugging
serialPutchar(serial_port, c); // sends c to the arduino
idea = 0; // resets the reset check value
}
lastSec = currSec; // sets the current second to the last second for next loop iteration
}
else if (state == 2){ // if the state is currently 2
stop(); // stop the stopwatch
}
else if (state == 0){ // if the state is currently 0
if (idea == 0){ // if the reset check value is currently zero
int zero = 0;
char z = (int) zero;
serialPutchar(serial_port, z); // sends "0" to the Arduino
idea = 1; // makes sure "0" is only sent once
}
}
else{ // just in case
}
lastClap = clap; // sets current clap value to lastClap for next loop iteration
}
// runs when program is run
int main(int argc, char *argv[]){
printf("hello\n"); // debugging
setup();
printf("there\n"); // debugging
while(1){ // loops forever
loop();
}
return 0; // will never be reached
}
Debugging code was left in for reference
Additional Code
Persistent Name for Serial Port
Running on Boot
In the file /etc/rc.local we added
/home/pi/stopwatch &
directly above the exit 0 at the end of the file. The ampersand forks the process, allowing the Pi to finish booting despite our code looping constantly.
Resources
Installing the Arduino IDE on the Raspberry Pi