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.

ECE412 Final – Automatic Toilet Paper Dispenser

Big Picture

In this project we used windows and Arduino and we started out with high hopes and big plans. We began brainstorming ideas for the project and originally planned to use a load sensor or another proximity sensor of some sort to be able to weigh, or ultimately tell when you were out of toilet paper. We decided that a load cell was too hard to incorporate mechanically and even if it was it wouldn’t be accurate enough to sense a few sheets of toilet paper. After we trashed that idea, we decided we would still have a sensor for when it was empty but we would use a interrupt sensor and a series of pullies tied in with the motor to show that the motor was turning but no more toilet paper was coming out. Well this plan also failed due to lack of time and mechanical availability. So we decided to try to perfect the simple action of automated toilet paper dispensing. 

Sample Demo

Schematic

The hardware of this project was mostly recycled from other projects. The Styrofoam casing and motors came from a previous project that was about RC cars using DC motors. Our hardware was fed through the existing and new holes and the board and wiring was all implemented on the opposite side to what the user would see. The motor was wired through a transistor and diode to protect the DC motor in case of feedback. We originally had a 5V power source but the output was too low for the motor to turn with the toilet paper attached. The PWM ports on the Arduino were used to change the power used for the DC motor. The photo infrared sensor acts as a trigger to activate the toilet paper dispenser for 3 seconds.

Code

The code for this project is a mixture of checking for interrupts in the PIR and if there are changes then the toilet paper dispensing is triggered and then resets after it is done. It is very similar code for paper towel dispensers that you would see in almost all public bathrooms. Our PIR was very sensitive so often the it would trigger multiple times in a row, but otherwise the code worked perfectly. There were plans to add a buzzer to the rig as shown in the code, but it never made it to the final product. Everything was coded in Arduino.

Dragon Bank: Music-related code snippet

For the speaker, we first modified a copy of the Game of Thrones theme to sound nice when repeated. Then we looked up every note frequency and wrote it out. We determined that the music sounded best at a speed of 200 bpm and found that the time an eighth note takes at this speed would be 150 ms.

Team Dracarys – Music composed for the speaker with the frequencies written out

When coding it, we set up 2 arrays. One array held the frequency of the note and the other held how long that note was to be played relative to the speed of an eighth note. So the first entry in the frequency array would correspond to the first note and would be 392.00. Then, because the note has a duration of 6 eighth notes, then a 6 went into the delay array. So the final arrays looked like this:

double frequencies[] = {392.00, 261.63, 311.13, 349.23, 392.00, 261.63, 311.13, 349.23, 293.66, 196.00, 0, 233.08, 261.63, 293.66, 196.00, 0, 233.08, 261.63, 293.66, 196.00, 0, 233.08, 261.63, 293.66, 0, 196.00, 0, 233.08, 0, 349.23, 233.08, 311.13, 293.66, 349.23, 233.08, 311.13, 293.66, 261.63, 174.61, 0, 207.65, 233.08, 261.63, 0, 174.61, 0, 207.65, 233.08, 261.63, 0, 174.61, 0, 207.65, 233.08, 261.63, 0, 174.61, 0, 207.65, 0};

int delays[] = {6, 6, 1, 1, 4, 4, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 1, 1, 4, 4, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

Then, one loop of the music was:

for(int i = 0; i < 60; i++){
 
   if(frequencies[i] == 0){
     OCR1A = 1;
   } else{
     OCR1A = F_CPU / (frequencies[i] * TIMER1_PRESCALER * (2^octave)) - 1;
   }
   for(int j = 0; j < delays[i]; j++){
     _delay_ms(150);
   }
}//for

Then, a variable called octave went back and forth between 0 and 1 to cause it to alternate octaves with each play through. This was then all put into a while-loop what would play the song only when told to by the master board. Then all of that was put into a loop that would run forever.