Motion Sensor Jingle Player – Code

The code included a custom library we built, the Alarm library. The library contains functionality that lets users build their own Jingles to be played, as well as some built-in, default jingles.

The note() method

The main part of the Alarm library is the Jingle class’s note() method, which simplifies the process of playing tones for the user. The note() function makes use of the Arduino tone() and delay() functions. The tone() function outputs a specified frequency to a specified output pin for a specified duration. Since the tone() function doesn’t wait for the note to complete before moving onto the next command, the delay() function is called so that the notes can be properly spaced.

To let users make jingles more easily, different musical notes are pre-programmed. The notes are set to the corresponding frequency that the Arduino’s tone() function will use to play the note.

One of the preset alarms


Wireless Data Transmission – Code

Transmitter Program

#define LASER_PIN           7
#define LASER_BAUDRATE      5  // bits per second
#define SIGNAL_HOLD_PERIOD  (1.0 / LASER_BAUDRATE) * 1000.0
#define SIGNAL_START_HOLD_PERIOD  SIGNAL_HOLD_PERIOD / 2.0

unsigned long transmit_begin;
byte c;
int message[10] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0};


int isNthBitSet (byte c, int n) {
  static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
  return ((c & mask[n]) != 0);
}

void transmitHoldStart() {
  while (millis() - transmit_begin < SIGNAL_START_HOLD_PERIOD) {}
}

void transmitHold() {
  //transmit_begin = millis();
  while (millis() - transmit_begin < SIGNAL_HOLD_PERIOD) {}
}

void transmitByte(byte c) {

  for (int idx=0; idx<8; idx++) {
    message[idx+1] = isNthBitSet(c, idx);
  }

  transmit_begin = millis();
  digitalWrite(LASER_PIN, message[0]);
  transmitHoldStart();

  for (int idx=1; idx<10; idx++) {
    transmit_begin = millis();
    digitalWrite(LASER_PIN, message[idx]);
    transmitHold();
  }
}

void serialEvent() {
  c = Serial.read();
  //if (!isPrintable(c)) { return; }
  //Serial.write("Transmitting '");
  transmitByte( c );
  //if (isPrintable(c)) {
    Serial.write(c);
  //}
  //Serial.write("&gt;&gt;&gt; ");
}


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LASER_PIN, OUTPUT);
  transmit_begin = 0;
  c = '\0';
  Serial.begin(9600);
  Serial.write("\r\nReady to transmit!\r\n");
  Serial.write("\n&gt;&gt;&gt; ");

}

void loop() {
  
}

Receiver program

#define REF_PIN       24
#define SIG_PIN          23
#define LOGIC_1_CUTOFF      0
#define LASER_BAUDRATE      5
#define SIGNAL_HOLD_PERIOD  (1.0 / LASER_BAUDRATE) * 1000.0
#define START_BIT           1
#define STOP_BIT            0

int bit_val;
static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
int buff[8] = {};
byte data = 0;
unsigned long receive_begin;
int bias = 0;
int bias_samp_size = 20;
int bias_samp_delay = 100;

void adjustSensorBias() {
  for (int i=0; i<bias_samp_size; i++) {
    bias += analogRead(SIG_PIN) - analogRead(REF_PIN);
    delay(bias_samp_delay);
  }
  bias /= bias_samp_size;
}

int sensorRead() {
  int val = analogRead(SIG_PIN) - analogRead(REF_PIN) - bias;
  Serial.write("sensorRead(): val = ");
  Serial.print(val);
  Serial.println();
  if (val < LOGIC_1_CUTOFF) { return 1; }
  return 0;
}

void poolBuffer() {
  int tmp = 0;
  for (int idx=0; idx<8; idx++) {
    tmp += buff[idx] * mask[idx];
  }
  data = (byte)tmp;
}

void receiveWait() {
  receive_begin = millis();
  while (millis() - receive_begin < SIGNAL_HOLD_PERIOD) {}
}

void laserRead() {
  receiveWait();
  for (int idx=0; idx<8; idx++) {
    buff[idx] = sensorRead();
    receiveWait();
  }
  if (sensorRead() != STOP_BIT) {
    receiveWait();
    receiveWait();
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(REF_PIN, INPUT);
  pinMode(SIG_PIN, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  adjustSensorBias();
}

void loop() {
  bit_val = sensorRead();

  //Serial.write("\r\nbit_val = ");
  //Serial.print(bit_val);
  //Serial.println();

  if (bit_val == START_BIT) {
    laserRead();
    poolBuffer();
    Serial.write("\r\ndata = ");
    Serial.write(data);
    Serial.println();
  }
}

Coin Sorter/Counter – Code

Main Arduino Code

#include<printing.h>                           //custom library
#include<LiquidCrystal.h>

LiquidCrystal lcd(12,13,8,9,10,11);            //sets pins for lcd
printing p();
#define SENSORPIN 2                            //dime
#define SENSORPIN2 3                           //nickel
#define SENSORPIN3 4                           //quarter

int sensorState = 0;
int lastState = 0;
int sensorState2 = 0;
int sensorState3 = 0;
int sum;                                                                             // keeps track of current money total
void setup() {      
  pinMode(SENSORPIN, INPUT);                  //initialize sensor as input 
  pinMode(SENSORPIN2, INPUT);                 //initialize sensor as input
  pinMode(SENSORPIN3, INPUT);                 //initialize sensor as input     
  digitalWrite(SENSORPIN, HIGH);              //set initial value for sensor as HIGH
  digitalWrite(SENSORPIN2, HIGH);             //set initial value for sensor as HIGH
  digitalWrite(SENSORPIN3, HIGH);             //set initial value for sensor as HIGH
  
  Serial.begin(9600);
}
 
void loop(){
  sensorState = digitalRead(SENSORPIN);        //reads sensor value
  sensorState2 = digitalRead(SENSORPIN2);      //reads sensor value
  sensorState3 = digitalRead(SENSORPIN3);      //reads sensor value
 
  if (sensorState == LOW) {                    //checks if sensor 1 beam is broken    
    delay(500);
    sum += 10;                                 //adds 10 to the current total
    displayLCD();
    p.printingDime();
 
  } 

   if (sensorState2 == LOW){                    //checks if sensor 2 beam is broken
    delay(500);
    sum += 5;                                   //adds 5 to current total
    displayLCD();
    p.printingNickel();
  }
  if(sensorState3 == LOW) {                     //checks if sensor 3 beam is broken
    delay(500);
    sum += 25;                                  //adds 25 to current total
    displayLCD();
    p.printingQuarter();
  }

  if (sensorState && !lastState) {
    Serial.println("Unbroken");
  } 
  if (!sensorState && lastState) {
    Serial.println("Broken");
  }
  lastState = sensorState;
}
void displayLCD(){                                                             //function to display total value
  lcd.clear();
  lcd.print("Total:");
  lcd.print(sum);
}

library.cpp – Our custom code library

#include "printing.h"
#inlcude "arduino.h"
#include <stdio.h>
printing::printing()
void printing::printingDime(){
	Serial.println("Break - Dime");
}
void printing::printingQuarter(){
	Serial.println("Break - Quarter");
}
void printing::printingNickel(){
	Serial.println("Break - Nickel");
}

library.h – Header file for our custom code library

#ifndef printing_h
#define printing_h

class printing
{
	public:
		printing();
		void printingDime();
		void printingQuarter();
		void printingNickel();
		
}

#endif

These are the three files we used to code the project, the first being the main Arduino file, the second being the custom library used in our main Arduino file, and lastly the header file used for the custom library. This code is responsible for detecting breaks in the IR break beams and adding to the count of the total amount in coins that has been sorted. The code for the IR breaks was mostly original with help from the Adafruit documentation/learning section specifically for the IR break beam sensors we used.

Timer and Stop Watch with LEDs – Code

The code above is used to maintain and countdown time for the timer/stopwatch in this project. It is set in the interrupt and is calculated for every second. Due to the nature of the LCD, it is required to use and display the time using an array. Therefore, the ten’s place of the minute, one’s place of the minute, ten’s place of the seconds and one’s place of the seconds is used to calculate time along with the interrupts. For the purpose of this project, the maximum value of time is 59 minutes, therefore the if else statement above considers the value in the format of ##:## and counts up from the one’s place of the seconds and once that reaches 0, increments the ten’s place by one and then repeats this til stop watch is stopped.

Carnival Arm Code Post Group 6

This code was intended for an ATMega328p and was coded using Atmel Studio 7. The purpose of the code is to detect if the microcontroller gets a shock and if it does send a signal to the buzzer to let the user know the won. We accomplished this by creating a while-true loop that goes on continuously until it detects a signal from the shock sensor, that is set as an input in PIN 5 of Port B, if it detects a shock it will generate a random integer between 0 and 5. If the integer that was generated is the same as the one specified in the code, in this case a 3, it will activate and deactivate the buzzer, set as an output on PIN 5 of Port C, letting the user know if they have won or not.

Sleep Timer Code

In a portion of our code we needed to look for a button press to change a variable. To do this we used a while loop that incremented a counter when the button was not pressed and changed the value when the button was pressed. This allowed for the user to edit the value for a set amount of time and then move on to the next portion of the code. Below is the code

 

counter = 0;
LCDWriteString(“SET MINUTES”);
LCDWriteIntXY(1, 2, minutes, 2);

//Get minutes
while(counter < 10)
{
_delay_ms(500);
LCDClear();

int temp = PIND & 0x01;
if (temp == 0x00)
{
counter += 1;
}
else
{
minutes += 1;
if (minutes > 59)
{
minutes = 0;
}
}

LCDWriteString(“SET MINUTES”);
LCDWriteIntXY(1, 2, minutes, 2);

}

Infrared Controlled Wah-Wah – Code Snippet

The programming of the microcontroller was accomplished using Atmel studio 7 on Windows 10.  The goal of converting the analog voltage produced by the Sharp IR sensor to a digital signal was accomplished using the ADC of the microcontroller. The ADC was setup in an ADC initializing function, ADCinit. PC5 was selected as the input for the ADC by setting the MUX0 and MUX2 to 1. The ADCSRA register was set up to enable the ADC, enable auto trigger, enable interrupts and set the prescaler to 64. Global interrupts were enabled in this function using the sei instruction. The output voltage of the sharp IR sensor was found to have a range of 0 to 3 volts depending on the distance. The ADC voltage reference was set to 3.3 volts to more closely match the output of the IR sensor as opposed to the 5 volt default. This was accomplished using AREF as the voltage reference by connecting the 3.3 volt output of the microcontroller to AREF pin with a jumper wire. The LED brightness was controlled with PWM. PWM was set up in the PWMinit function. The clock was set up with no prescaler and using CTC mode. In this mode the OCR1A acts as the top value of the counter while the OCR1B is the value to be compared to. Interrupt service routines were used to change the duty cycle based on the ADC value passed into the duty variable and then by setting OCR1B compare value to duty.  The result of the program was a smooth fluctuation in the brightness of the LED based on the distance of a hand or object from the sensor.

The Wah circuit was combined with the microcontroller by inserting the LED and LDR into a heat-shrink tube in order to have the light passed to the LDR directly related to the LED without outside light interference. The resulting behavior of the LED based on hand position can be observed in the video above.

Bike Odometer & Speedometer – Code

We wrote code for the project for both the Atmel Xplained board in Atmel Studio and an Arduino Uno (has the same processor as the Xplained Board). Originally, the Arduino was used just for proof-of-concept testing and for a user friendly testing platform to iron out any unforeseen kinks with the program flow or mathematical computations. Once that was completed, development switched to Atmel Xplained board. The end functionality of the code written for both boards is fairly comparable except for the speedometer module. A critical component to the speed calculation is the elapsed time between the voltage drops of the Hall effect sensor. For the Arduino Uno this was no problem as an external clock source separate from the Atmega 328p is integrated into the board. In addition to build in functions that make interfacing with the clock extremely easy. On the other hand, the Atmel Xplained board has no external clock source. So all timing had to be done utilizing timers based off the CPU clock speed. Overall, this created a more complex piece of code with worse functionality.

 

Optical Theremin – Code Snippet

From our project, the interesting thing about our code is how the output signals are converted into realistic musical notes. The original approach we were going to use the received signals as a corresponding output using a speakers. But, we actually decided to create a realistic version which takes in the signal and translates them into real-world musical notes; therefore that is the most interesting portion of our code. The above photo only portray the first few conversion because including more would just be repetitive. Also, all the code is a series of if statements which tells certain signals to convert to particular musical notes.

LED maze, The Code

Code for ray tracing for the LED maze

One interesting aspect of the code is the implementation of ray tracing. Ray tracing is basically casting a “ray” from a point outwards, gathering data about when the ray encounters an object, and using that data to interact with the surroundings. In this project, Ray tracing is used to find out where the visible walls will be. A ray is cast from the user’s current position, and when it encounters a wall in the maze, it instructs the program to activate the led at that position. It repeats this all the way around the user, until the entire view of the maze that the user would have while within the maze is constructed. This is referred to as the “frame” and is how the program decides which LEDs to have on after each move made by the user. This does result in a small delay between each move until the next frame is displayed, but also gets the desired result of only showing the parts of the maze wold be visible in the maze to a user.