Add "Software" chapter, move to minted
This commit is contained in:
@ -1,23 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2012 Nathanaël Restori
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
@ -40,7 +42,43 @@ static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
static IPAddress ip = IPAddress(192, 168, 1, 210);
|
||||
static IPAddress timeserver = IPAddress(192, 43, 244, 18);
|
||||
|
||||
P(indexHtml) = "<!DOCTYPE html><html><head><meta charset='utf-8'/><title>Station Météo</title><style>html, body{background: #000;color: #fff;}body{font-family: 'DejaVu Sans', Verdana, Arial, sans-serif;font-size: 100%;margin: 0;padding: 0;}#home{background: #000;color: #fff;margin: 1em;padding: 0;}#home h1{color: #f7c000;font-size: 2em;margin: 1em;text-align: center;}#home p{background: #111;border: 1px solid #444;font-size: 1.5em;list-style-type: none;padding: 0;width: 100%;text-align: center;}#home table{background: #111;border: 1px solid #444;font-size: 1.5em;list-style-type: none;padding: 0;width: 100%;text-align: center;}#footer{background: #000;color: #888;font-size: 0.8em;margin: 1em;text-align: center;padding: 0;}</style></head><body><div id='home'><h1>Station Météo</h1><table><tr><th>Temps</th><th>T [°C]</th><th>P [Pa]</th><th>Alt [m]</th><th>Hr [%]</th><th>Lx [lux]</th></tr><tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr></table><p><label>Intervale de mise à jour (en secondes) : </label><input id='interval' type='number' value=2/></p></div><div id='footer'> par Nathanaël Restori </div><script>function updateInfo(){var xhr=new XMLHttpRequest();xhr.open('GET', '/sensors.json');xhr.onreadystatechange=function(){if (xhr.readyState==4 && xhr.status==200){var response=JSON.parse(xhr.responseText);var rows=document.getElementsByTagName('tr');var cell=rows[1].firstChild;var index=0;while (cell){cell.firstChild.nodeValue=response.sensors[index].data;cell=cell.nextSibling;index++;}}};xhr.send(null);}updateInfo();var updateID=setInterval(updateInfo, 2000);var interval=document.getElementById('interval');interval.addEventListener('change', function(e){clearInterval(updateID);updateID=setInterval(updateInfo, e.target.value*1000);}, true);</script></body></html>";
|
||||
P(indexHtml) = "<!DOCTYPE html><html><head><meta charset='utf-8'/\
|
||||
><title>Station Météo</title><style>html, body{ba\
|
||||
ckground: #000;color: #fff;}body{font-family: 'De\
|
||||
jaVu Sans', Verdana, Arial, sans-serif;font-size:\
|
||||
100%;margin: 0;padding: 0;}#home{background: #00\
|
||||
0;color: #fff;margin: 1em;padding: 0;}#home h1{co\
|
||||
lor: #f7c000;font-size: 2em;margin: 1em;text-alig\
|
||||
n: center;}#home p{background: #111;border: 1px s\
|
||||
olid #444;font-size: 1.5em;list-style-type: none;\
|
||||
padding: 0;width: 100%;text-align: center;}#home \
|
||||
table{background: #111;border: 1px solid #444;fon\
|
||||
t-size: 1.5em;list-style-type: none;padding: 0;wi\
|
||||
dth: 100%;text-align: center;}#footer{background:\
|
||||
#000;color: #888;font-size: 0.8em;margin: 1em;te\
|
||||
xt-align: center;padding: 0;}</style></head><body\
|
||||
><div id='home'><h1>Station Météo</h1><table><tr>\
|
||||
<th>Temps</th><th>T [°C]</th><th>P [Pa]</th><th>A\
|
||||
lt [m]</th><th>Hr [%]</th><th>Lx [lux]</th></tr><\
|
||||
tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0<\
|
||||
/td><td>0</td></tr></table><p><label>Intervale de\
|
||||
mise à jour (en secondes) : </label><input id='i\
|
||||
nterval' type='number' value=2/></p></div><div id\
|
||||
='footer'> par Nathanaël Restori </div><script>fu\
|
||||
nction updateInfo(){var xhr=new XMLHttpRequest();\
|
||||
xhr.open('GET', '/sensors.json');xhr.onreadystate\
|
||||
change=function(){if (xhr.readyState==4 && xhr.st\
|
||||
atus==200){var response=JSON.parse(xhr.responseTe\
|
||||
xt);var rows=document.getElementsByTagName('tr');\
|
||||
var cell=rows[1].firstChild;var index=0;while (ce\
|
||||
ll){cell.firstChild.nodeValue=response.sensors[in\
|
||||
dex].data;cell=cell.nextSibling;index++;}}};xhr.s\
|
||||
end(null);}updateInfo();var updateID=setInterval(\
|
||||
updateInfo, 2000);var interval=document.getElemen\
|
||||
tById('interval');interval.addEventListener('chan\
|
||||
ge', function(e){clearInterval(updateID);updateID\
|
||||
=setInterval(updateInfo, e.target.value*1000);}, \
|
||||
true);</script></body></html>";
|
||||
|
||||
// no-cost stream operator as described at
|
||||
// http://sundial.org/arduino/?page_id=119
|
||||
@ -57,12 +95,14 @@ WebServer webserver(PREFIX, 80);
|
||||
byte packetBuffer[ NTP_PACKET_SIZE];
|
||||
EthernetUDP Udp;
|
||||
|
||||
void defaultCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
|
||||
void defaultCmd(WebServer &server, WebServer::ConnectionType type,
|
||||
char *url_tail, bool tail_complete) {
|
||||
server.httpSuccess();
|
||||
server.printP(indexHtml);
|
||||
}
|
||||
|
||||
void sensorsJsonCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
|
||||
void sensorsJsonCmd(WebServer &server, WebServer::ConnectionType type,
|
||||
char *url_tail, bool tail_complete) {
|
||||
float temperature = bmp.readTemperature();
|
||||
int32_t pressure = bmp.readPressure();
|
||||
float altitude = bmp.readAltitude();
|
||||
@ -78,7 +118,10 @@ void sensorsJsonCmd(WebServer &server, WebServer::ConnectionType type, char *url
|
||||
server.httpSuccess("application/json");
|
||||
|
||||
server << "{ \"sensors\": ["
|
||||
<< "{\"data\":\"" << time.hour() << ":" << time.minute() << ":" << time.second() << " " << time.day() << "/" << time.month() << "/" << time.year() << "\"},"
|
||||
<< "{\"data\":\"" << time.hour() << ":" << time.minute()
|
||||
<< ":" << time.second() << " " << time.day() << "/"
|
||||
<< time.month() << "/" << time.year() << "\"},"
|
||||
|
||||
<< "{\"data\":" << temperature << "},"
|
||||
<< "{\"data\":" << pressure << "},"
|
||||
<< "{\"data\":" << altitude << "},"
|
||||
@ -113,17 +156,22 @@ void sendNTPpacket() {
|
||||
delay(1000);
|
||||
if ( Udp.parsePacket() ) {
|
||||
// We've received a packet, read the data from it
|
||||
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
|
||||
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, esxtract the two words:
|
||||
// the timestamp starts at byte 40 of the received packet and is
|
||||
// four bytes, or two words, long. First, esxtract the two
|
||||
// words:
|
||||
|
||||
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
|
||||
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
|
||||
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
|
||||
// this is NTP time (seconds since Jan 1 1900):
|
||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
|
||||
// Unix time starts on Jan 1 1970. In seconds, that's
|
||||
// 2208988800:
|
||||
const unsigned long seventyYears = 2208988800UL;
|
||||
// subtract seventy years:
|
||||
unsigned long epoch = secsSince1900 - seventyYears + TIMEZONE;
|
||||
@ -153,15 +201,12 @@ void setup() {
|
||||
tsl.begin();
|
||||
chronodot.begin();
|
||||
|
||||
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||
//tsl.setGain(TSL2561_GAIN_0X); // set no gain (for bright situtations)
|
||||
tsl.setGain(TSL2561_GAIN_16X); // set 16x gain (for dim situations)
|
||||
//tsl.setGain(TSL2561_GAIN_0X); // bright situtations
|
||||
tsl.setGain(TSL2561_GAIN_16X); // dim situations
|
||||
|
||||
// Changing the integration time gives you a longer time over which to sense light
|
||||
// longer timelines are slower, but are good in very low light situtations!
|
||||
tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS); // shortest integration time (bright light)
|
||||
//tsl.setTiming(TSL2561_INTEGRATIONTIME_101MS); // medium integration time (medium light)
|
||||
//tsl.setTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim light)
|
||||
tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS); // bright light
|
||||
//tsl.setTiming(TSL2561_INTEGRATIONTIME_101MS); // medium light
|
||||
//tsl.setTiming(TSL2561_INTEGRATIONTIME_402MS); // dim light
|
||||
|
||||
Udp.begin(8888);
|
||||
sendNTPpacket();
|
||||
|
@ -64,10 +64,18 @@
|
||||
<div id='home'>
|
||||
<h1>Station Météo</h1>
|
||||
<table>
|
||||
<tr><th>Temps</th><th>T [°C]</th><th>P [Pa]</th><th>Alt [m]</th><th>Hr [%]</th><th>Lx [lux]</th></tr>
|
||||
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
|
||||
<tr>
|
||||
<th>Temps</th><th>T [°C]</th><th>P [Pa]</th><th>Alt
|
||||
[m]</th><th>Hr [%]</th><th>Lx [lux]</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p><label>Intervale de mise à jour (en secondes) : </label><input id='interval' type='number' value=2 /></p>
|
||||
<p>
|
||||
<label>Intervale de mise à jour (en secondes) : </label>
|
||||
<input id='interval' type='number' value=2 />
|
||||
</p>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
par Nathanaël Restori
|
||||
|
Reference in New Issue
Block a user