Component | Quantity | Comment |
---|---|---|
Main PCB : Satchakit (to be confirmed) | 1 | Yet to be made |
WiFi module | 1 | I bought this one |
RTC module | 1 | Optional |
RGB LEDs | 13 | 12 for the hours, 1 for the minutes |
Resistances | n | value to be calculated according to LEDs |
Continuous Servomotor for the minutes | 1 | Here is the model I bought |
LED matrix or LDC screen | 1 | To be determined |
... | ... | ... |
/* Adapted from Example 2 for Chaplex - a library to control charlieplexed leds
* *** controlling led bar with output via timer2 interrupt ***
* This sketch turns ON a LED every hour. Between One and Twelve, the previous lEDs stay ON, when a new cycle begins, all LEDs are switched OFF except for the first one.
* only tested with Arduino Uno
*/
#include "Chaplex.h"
byte ctrlpins[] = {13,12,11,10}; //Arduino pins controlling charlieplexed leds
#define PINS 4 //number of these pins
#define DELAY 0 //speed of switching leds in bar on and off
Chaplex myCharlie(ctrlpins, PINS); //control instance
charlieLed myLeds[12] = {
{1, 0}, {2, 1}, {3, 2}, {2, 3}, {1, 2}, {0, 1}, {0, 2}, {2, 0}, {3, 0}, {0, 3}, {1, 3}, {3, 1}
};
byte timer2TCNT2 = 178; //preload timer 256-16MHz/1024/78 = near 5 ms
void setup() {
// initialize timer2
noInterrupts(); //disable all interrupts
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = timer2TCNT2;
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); //prescaler 1024 = 64 micro secs
TIMSK2 |= (1 << TOIE2); //enable timer overflow interrupt
interrupts(); //enable all interrupts
}
ISR(TIMER2_OVF_vect) { //timer2 interrupt routine
myCharlie.outRow(); //output for one led row
TCNT2 = timer2TCNT2; //preload timer for next interrupt
}
void loop() {
for (int i=0; i< 12; i++) {
myCharlie.ledWrite(myLeds[i], ON); //first part of the loop : switching all the LEDs ON one after the other
delay(3600000); //actual delay for switching the next LED ON
}
for (int i=0; i<12; i++) {
myCharlie.ledWrite(myLeds[i], OFF); //first part of the loop : switching all the LEDs OFF one after the other
delay(DELAY); //actual delay for switching the next LED OFF
}
void allClear();
}
Week13 - Final from Thomas Feminier on Vimeo.
#include <Servo.h>
#define TURN_TIME 500 //in millis
Servo myservo;
void setup() {
myservo.attach(10);
// Initially the servo must be stopped
myservo.write(90);
}
void loop() {
// Start turning clockwise
myservo.write(0);
// Go on turning for the right duration
delay(TURN_TIME);
// Stop turning
myservo.write(90);
// Wait for 2s
delay(2000);
}
Number of teeth on the small gear (A)= 12 Number of teeth on the main gear (B)= 60 The Rotation ratio (R) = A/B = 12/60 = 1/5 = 0,2 So the small gear must do 5 complete revolutions for the main one to do one revolution. So 1h = 5x360° on A = 1800° and so 1min = 1800/60 = 30°.With this, I know that the small gear must turn 30° every minute.
110 RPM = 110*360 per min. = 39 600° per 60sec. = 660° per sec. = 1/22sec per 30° = 0.04545455 130 RPM = 130*360 per min. = 46 800° per 60sec. = 780° per sec. = 1/26sec per 30° = 0.03846154
Item | Dimensions | Quantity |
---|---|---|
Neopixel RGB LEDs![]() |
3,5x3,5mm | 12 |
Neopixel RGB LEDs (same ones but larger)![]() |
5x5mm | 60 |
0.1µF capacitors![]() |
72 |
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
#include
#ifdef __AVR__
#include
#endif
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN 6
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 1
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval = 500; // delay for half a second
void setup() {
pixels.begin(); // This initializes the NeoPixel library.
}
void loop() {
// For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
for(int i=0;i<NUMPIXELS;i++){
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0,0,255)); // Full blue.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(delayval); // Delay for a period of time (in milliseconds).
pixels.setPixelColor(i, pixels.Color(0,255,0)); // Full green.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(delayval);
pixels.setPixelColor(i, pixels.Color(255,0,0)); // Full red.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(delayval);
}
}
And the result :Final3 - Neopixel test from Thomas Feminier on Vimeo.
Final3 - ringstests from Thomas Feminier on Vimeo.
Final3 - Matrix test1 from Thomas Feminier on Vimeo.
//Byte array of bitmap of 32 x 16 px:
img [] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x8, 0x8,
0x0, 0x0, 0x4, 0x90, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x16,
0x34, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x4, 0x90, 0x0, 0x0,
0x8, 0x8, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
}
Here is a test code for display alternatively all the types of icon I chose :
#include <Adafruit_GFX.h> // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
#define LAT A3
#define OE 9
#define A A0
#define B A1
#define C A2
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
const unsigned char PROGMEM sun[] =
// SUN
{
0x0, 0x8, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x1c, 0x0,
0x0, 0x0, 0x22, 0x0, 0x0, 0x1, 0x63, 0x40, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x1c,
0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
};
const unsigned char PROGMEM suncloud[] =
// SUN AND CLOUDS
{
0x0, 0x8, 0x0, 0x0, 0x0, 0x80, 0xf0, 0x0, 0x0, 0x49, 0xf8, 0x0, 0x0, 0x1d, 0xfc,
0x0, 0x0, 0x23, 0xfe, 0x0, 0x1, 0x67, 0xff, 0x0, 0x0, 0x27, 0xff, 0x0, 0x0, 0x1f,
0xff, 0x80, 0x0, 0x7f, 0xff, 0x80, 0x0, 0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0x80, 0x1,
0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
};
const unsigned char PROGMEM rain[] =
// RAIN
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, 0xf8, 0x0, 0x0, 0x1, 0xfc,
0x0, 0x0, 0x3, 0xfe, 0x0, 0x0, 0x7, 0xff, 0x0, 0x0, 0x7, 0xff, 0x0, 0x0, 0x1f,
0xff, 0x80, 0x0, 0x3f, 0xff, 0x80, 0x0, 0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0x80, 0x1,
0xff, 0xff, 0x0, 0x0, 0x22, 0x48, 0x0, 0x0, 0x66, 0xd8, 0x0, 0x0, 0x4c, 0x90, 0x0,
0x0, 0x8, 0x0, 0x0,
};
const unsigned char PROGMEM cloud[] =
// CLOUD
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, 0xf8, 0x0, 0x0, 0x1, 0xfc,
0x0, 0x0, 0x3, 0xfe, 0x0, 0x0, 0x7, 0xff, 0x0, 0x0, 0x7, 0xff, 0x0, 0x0, 0x1f,
0xff, 0x80, 0x0, 0x3f, 0xff, 0x80, 0x0, 0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0x80, 0x1,
0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
};
void setup()
{
matrix.begin();
}
void loop() {
// draw a sun
matrix.drawBitmap(0, 0, sun, 32, 16, matrix.Color333(4,7,0));
delay (2000);
matrix.drawBitmap(0, 0, cloud, 32, 16, matrix.Color333(5,7,7));
delay (2000);
// clear matrix
matrix.fillScreen(0);
delay (0);
matrix.drawBitmap(0, 0, rain, 32, 16, matrix.Color333(0,4,7));
matrix.drawBitmap(0, 0, cloud, 32, 16, matrix.Color333(5,7,7));
delay (2000);
// clear matrix
matrix.fillScreen(0);
delay (0);
matrix.drawBitmap(0, 0, cloud, 32, 16, matrix.Color333(5,7,7));
delay (2000);
matrix.fillScreen(0);
delay (0);
//write the temperature
matrix.setCursor(8, 4);
matrix.setTextSize(1);
matrix.setTextColor(matrix.Color333(4,7,0));
matrix.print('2');
matrix.print('2');
matrix.drawCircle(21, 5, 1, matrix.Color333(4,7,0));
delay (2000);
matrix.fillScreen(0);
delay (0);
}
And the demo :Final3 - Icons test from Thomas Feminier on Vimeo.
<html><body>
<?php
include('lib/forecast.io.php');
$param = $_GET[param];
$apiKeyParam = "541288a68a7158ad6065fe8c0102123e";
$latParam = "48.868438";
$lonParam = "2.348573";
$units = 'auto';
$lang = 'en';
if($param != "MINUTE" && $param != "HOUR" && $param != "DATE" ) {
$forecast = new ForecastIO($apiKeyParam, $units, $lang);
$condition = $forecast->getCurrentConditions($latParam, $lonParam);
$conditions_week = $forecast->getForecastWeek($latParam, $lonParam);
}
switch($param) {
case "DATE":
echo date('D')." ".date('j')." ".date('F');
break;
case "HOUR":
echo date('h');
break;
case "MINUTE":
echo date('i');
break;
case "CURRENT_TEMP":
echo round($condition->getTemperature());
break;
case "CURRENT_ICON":
echo $condition->getIcon();
break;
case "MAX_TEMP_TOMORROW":
echo "MAX_TEMP_TOMORROW=" . round($conditions_week[1]->getMaxTemperature());
//echo round($conditions_week[1]->getMaxTemperature());
break;
case "ICON_TOMORROW":
echo $conditions_week[1]->getIcon();
break;
default:
echo "error";
break;
}
?>
</body>
</html>
The nice thing with this is that I won't have to parse the data because the .php does that for me : I just have to request the right parameter, and I only get the value. A simple example of that in a web browser :
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <SPI.h>
const char* ssid = "*******";
const char* password = "*******";
const char* host = "www.tomfem.fr";
byte current_temp;
byte current_icon;
byte date;
byte hour, last_hour;
byte minute, last_minute;
void setup() {
Serial.begin(115200);
delay(100);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
int value = 0;
void loop() {
delay(5000);
++value;
Serial.print("connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
///////////// Request for the date //////////////
String url = "/php/weather.php?param=DATE";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(2000);
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
hour = line.toInt();
}
///////////// Request for the hour //////////////
url = "/php/weather.php?param=HOUR";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(2000);
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
hour = line.toInt();
}
///////////// Request for the minutes //////////////
url = "/php/weather.php?param=MINUTE";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(2000);
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
minute = line.toInt();
}
///////////// Request for the seconds //////////////
url = "/php/weather.php?param=SECOND";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(2000);
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
minute = line.toInt();
}
///////////// Request for the current temperature //////////////
url = "/php/weather.php?param=CURRENT_TEMP";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(2000);
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
current_temp = line.toInt();
}
///////////// Request for the current icon //////////////
url = "/php/weather.php?param=CURRENT_ICON";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(2000);
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
current_temp = line.toInt();
}
Serial.println();
Serial.println("closing connection");
With the ESP8266 Huzzah board that I bought, I can directly load Arduino sketches using a FTDI cable. This process is explained here.