Firstly, we would like to apologize for turning in our final blog late. Personal schedule conflicts and time management issues lead us to complete the project at a slower pace than anticipated. Our project’s latency was also in part caused the fact that we did not receive our Edison kit, which pressed us for time when it came to completing the clock’s systems that relied on use of the Edison. Nevertheless, we learned a lot about the Edison chip while making an attempt to create our own clock. Overall, we greatly enjoyed the experience of being able to participate in this competition. If we can work together again, I would hope that we would be able to connect the buttons we made to the Raspberry pi for audio/recording control rather than having to connect it to a computer. In addition, we would probably have used interrupts to make it so the clock hand doesn't just go around in circles to reset.
This is how we connected the stepper motor to the calibration pin with set screw couplers. It can reliably turn the pin when secured to the back half of the clock.
Final Arduino Code:
#include <Dhcp.h>
#include <Dns.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <Stepper.h>
#include <Stepper.h>
const int stepsPerRevolution=60;
#include <SPI.h>
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper mystepper(stepsPerRevolution, 5, 4, 3, 2);
int stepCount=0;
// the previous reading from the analog input
int status = WL_IDLE_STATUS;
char ssid[] = "SSID"; // network SSID
char pass[] = "Passcode"; // network password
unsigned int localPort = 2390; // local port to listen for UDP packets
IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv != "1.1.0") {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
Serial.println("\nStarting connection to server...");
Udp.begin(localPort);
}
void loop() {
myStepper.setSpeed(motorSpeed);
// step 1/100 of a revolution:
myStepper.step(stepsPerRevolution / 100);
delay(59000);
if( digitalRead(0)==LOW && digitalRead(1)==LOW)
{
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if (Udp.parsePacket()) {
Serial.println("packet received");
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
unsigned long secsSince1900 = highWord << 16 | lowWord;
unsigned long epoch = secsSince1900 - 2208988800UL;
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600);
// print the hour (86400 equals secs per day)
Serial.print(':');
if (((epoch % 3600) / 60) < 10) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ((epoch % 60) < 10) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
}
if((epoch%86400L/3600)==12&&((epoch % 3600) / 60)==0){
while(digitalRead(0)==LOW && digitalRead(1)==LOW)
{
myStepper.setSpeed(100);
myStepper.step(10);
}
}
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
//Serial.println("1");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
//Serial.println("2");
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
//Serial.println("3");
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
Admittedly, the above code has a flaw where instead of calibrating, it merely waits until the conditions are met at midnight. There are pins connecting to the hour and minute hand that form a switch with the arduino (0 and 1 pins).
Raspberry Pi
We set up a system which requires one to be connected to a computer in order to use it…. But it can record and playback audio.
Arecord filename.wav -record function\
Hit ctrl-c to stop recording
Mpv filename.wav to play the recorded audio