BoschのBME280(Temp, Humid, Press) と DallasセミコンのDS1820(Temp)のデータを、それぞれさくらの別ファイルに転送するプログラムを作成した。
これによる期待効果:
観測パラメータを追加する場合、データファイルのFieldが変化するため、既存のデータ処理プログラム(Python)を都度直さなければならないが、追加データを別ファイル化することで、Python_Programは独立して作成できる。その後ShellScriptで他のデータ処理と併記することで、一連のグラフ作成などの作業が容易になる。
今回の実験:
ArduinoのProgramにおいて、BME280センサーとDS1820センサーのデータを取り込んだ後、さくらサーバーにコネクトして、GETモードで、それぞれのセンサーデータを別ファイルにストアできるか確認した。 → OK!!
プログラム構成:
① #include設定:
Dallas, BME280に必要なLibraryセット
② Dallas, BME280に必要なパラメータ、変数などの初期設定
③ Ethernet Shild Mac address、server port設定
④ NTP Server設定 (1日1回パラメターのリセットをするため、時刻を計測する)
⑤ sakura server IP 設定
⑥ void setup() 設定
// Ethernet intialize
// bme280 setting レジスタ設定
// Dallas DS18B20 setup
⑦ タイマー設定のためのパラメータ設定
⑧ void loop() 実行文
・実行文の全体を、HTTP送信の時間間隔で囲む;if文でタイマーを回す
・BME280 measurement
・ Dallas DS18B20 measurement
・digitalClockDisplay()による、時刻(日時秒)の取得
・さくらサーバーにコネクト
・bme280 data sending to bme280test.txt in sakura server
・ds1820 data sending to ds1820test.txt in sakura server
・さくらサーバコネクト停止
・時刻日付が変わったところで、雨量計のパラメータ(日累積不良)0リセット
実行終了
⑨ サブルーチン関数
/*——– BME280 code ———-*/
/*——– digitalClockDisplay code ———-*/
/*——– inputDigit code ———-*/
/*——– NTP code ———-*/
END
Program例:
/* aterm_BME280_IC2_dallas1820_test2.uno
————————————————-
2017/05/26 rev 0.1:
BME280(Temp, Humid, Press) + DallasDS1820(Temp)のデータ転送
さくらサーバーでBME,DSデータを。それぞれ別ファイルにstoreする
————————————————-
Ruouter –> Aterm 192.168.10.1
byte ip[] = {192,168,10,135 }; // Aterm router address 2017/05/26
Why NTP server use? — 毎日0時に雨量積算をリセットするためにNTP serverが必要
———————————————-
// sakuraデータログ directory home/www/logdata/testlog
// client.write(“GET /logdata/testlog/ds1820てstlog.php?temp=”);
// –> home/www/logdata/testlog/ds1820てst.txt
~~~~~~
*/
/// Dallas setting
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/// BME280 setting
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
///////////////////// dallas_DS18B20 setting
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define SENSOR_BIT 9
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
///////////////////// Bosch BME280 setting
#define BME280_ADDRESS 0x76
unsigned long int hum_raw,temp_raw,pres_raw;
signed long int t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
///////////////////////////////////////////////////////
// server port
#define PORT 80
//Ethernet Shild Mac address of arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFA, 0xEA };
//Ethernet Shild IP address of arduino
byte ip[] = {192,168,10,135 }; // Aterm router address 2017/05/26
//———————————————————
// NTP Servers:
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov
const int timeZone = 9; // Japan
//const int timeZone = -5; // Eastern Standard Time (USA)
EthernetUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
//———————————————————–
// sakura server IP
byte server[] = {219, 94, 129, 150 };
// generate clinet
EthernetClient client;
//———————————————————–
// temp setting
float temp;
float temp_C;
float temp_gnd;
int ii;
String str_temp_LM60, str_cds; //未使用
// NTP variable setting
String strDate, strHH, strMM, strSS;
int mm,ss;
////////////////////////////////////////////////////////
void setup()
{
Serial.begin(9600);
while (!Serial) ; // Needed for Leonardo only
delay(250);
// Ethernet intialize
Ethernet.begin(mac, ip);
delay(1000);
Udp.begin(localPort);
Serial.println(“waiting for sync”);
delay(2000);
setSyncProvider(getNtpTime);
//delay(3000);
// bme280 setting
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
Wire.begin();
writeReg(0xF2,ctrl_hum_reg);
writeReg(0xF4,ctrl_meas_reg);
writeReg(0xF5,config_reg);
readTrim();
//Dallas DS18B20 setup
//start serial port
//Serial.begin(9600);
//Serial.println(“Dallas Temperature IC Control Library Demo”);
//Start up the library
sensors.setResolution(SENSOR_BIT);
sensors.begin();
}
unsigned long timer;
unsigned long t0=millis();
unsigned long ti=millis();
time_t prevDisplay = 0; // when the digital clock was displayed
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void loop()
{
/////////////////////////////////////////////////////////////////////////////////
///// execute HTTP PHP every 300sec (5min)////
timer = millis() – t0;
if (timer >=10000) // mesurement interval setting : 10sec
{
/// BME280 measurement /////////////////////////////
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
Serial.print(“TEMP : “);
Serial.print(temp_act);
Serial.print(” DegC PRESS : “);
Serial.print(press_act);
Serial.print(” hPa HUM : “);
Serial.print(hum_act);
Serial.println(” %”);
//// Dallas DS18B20 measurement ///////////////////////////
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
// Serial.print(“Requesting temperatures…”);
sensors.requestTemperatures(); // Send the command to get temperatures
// Serial.println(“DONE”);
float temp_gnd;
temp_gnd = sensors.getTempCByIndex(0);
Serial.print(“Temperature for DS18B20 1 (index 0) is: “);
Serial.println(sensors.getTempCByIndex(0));
Serial.print(“temp_gnd = “);
Serial.println(temp_gnd);
Serial.println(“——————————-“);
Serial.println(“”);
//////////////////////////////////////////////////
if (now() != prevDisplay) { //update the display only if time has changed
prevDisplay = now();
digitalClockDisplay();
Serial.print(strDate); //
Serial.print(” “);
Serial.print (strHH) ;
Serial.print (“:”) ;
Serial.print(strMM) ;
Serial.print (“:”) ;
Serial.print (strSS) ;
Serial.println (” “) ;
}
/////////////////////////////////////////////////////////////////
/////////// send data to sakura server //////////////
if (client.connect(server, 80)) {
Serial.println(“—– check HTTP GET sending data ——-“);
//sakura web server PHP Script GET // testlog test case
// sakuraデータログ directory home/www/logdata/testlog
// client.write(“GET /logdata/testlog/ds1820testlog.php?temp=”); –> home/www/logdata/testlog/ds1820test.txt
// client.write(“GET /logdata/testlog/bme280testlog.php?temp=”); –> home/www/logdata/testlog/bme280test.txt
///// bme280 data sending to bme280test.txt in sakura server
client.write(“GET /logdata/testlog/bme280testlog.php?temp_act=”); //OK
client.print(temp_act); // bme280 temperature
client.write(“&press_act=”); // bme280 pressure
client.print(press_act);
client.write(“&hum_act=”); // bme280 humidity
client.print(hum_act);
client.write(” HTTP/1.1\n”);
client.write(“HOST:miyasan.sakura.ne.jp\n\n”);
///// ds1820 data sending to ds1820test.txt in sakura server
client.write(“GET /logdata/testlog/ds1820testlog.php?temp_gnd=”); //OK
client.print(temp_gnd); // ds1820 temperature
client.write(“&temp_act=”); // bme280 temperature
client.print(temp_act);
client.write(” HTTP/1.1\n”);
client.write(“HOST:miyasan.sakura.ne.jp\n\n”);
//////////
Serial.print(“timer(msec) = “);
Serial.println(timer);
Serial.println(“”);
//parameter of rain initilize;
//num = 0 ;
client.stop(); // <——————Sever disconect
}
else {
// 接続終了
client.stop();
Serial.println (“Server disconnected ……….”) ;
Serial.print(“timer(msec) = “);
Serial.print(timer);
Serial.println(“”);
}
////////////////// parameter initilize
//num = 0 ;
t0=millis();
///////////////////////////////////////////////////////////////////////////////////////
if (strHH==”0″ && (strMM==”0″ || strMM==”1″ || strMM ==”2″ || strMM ==”3″ || strMM ==”4″ ) )
//if (strHH==”12″ && (strMM==”0″ || strMM==”1″ || strMM ==”2″ || strMM ==”3″ || strMM ==”4″ ) ) //test reset
{
//Serial.print (“cum = “) ;
//Serial.println (cum) ;
//Serial.print (“reset timer cum = “) ;
//cum = 0;
// Serial.println (cum) ;
}
} /// END Excute HTTP loop
} /// END void() loop
//////////// sub-routine void() //////////////////////////
//////////////////////////////////////////////////////////
/*——– BME280 code ———-*/
void readTrim()
{
uint8_t data[32],i=0;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,24);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xA1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,1);
data[i] = Wire.read();
i++;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,7);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
dig_T1 = (data[1] << 8) | data[0];
dig_T2 = (data[3] << 8) | data[2];
dig_T3 = (data[5] << 8) | data[4];
dig_P1 = (data[7] << 8) | data[6];
dig_P2 = (data[9] << 8) | data[8];
dig_P3 = (data[11]<< 8) | data[10];
dig_P4 = (data[13]<< 8) | data[12];
dig_P5 = (data[15]<< 8) | data[14];
dig_P6 = (data[17]<< 8) | data[16];
dig_P7 = (data[19]<< 8) | data[18];
dig_P8 = (data[21]<< 8) | data[20];
dig_P9 = (data[23]<< 8) | data[22];
dig_H1 = data[24];
dig_H2 = (data[26]<< 8) | data[25];
dig_H3 = data[27];
dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
dig_H6 = data[31];
}
void writeReg(uint8_t reg_address, uint8_t data)
{
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(reg_address);
Wire.write(data);
Wire.endTransmission();
}
void readData()
{
int i = 0;
uint32_t data[8];
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,8);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
signed long int calibration_T(signed long int adc_T)
{
signed long int var1, var2, T;
var1 = ((((adc_T >> 3) – ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) – ((signed long int)dig_T1)) * ((adc_T>>4) – ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
unsigned long int calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
var1 = (((signed long int)t_fine)>>1) – (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
if (var1 == 0)
{
return 0;
}
P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
if(P<0x80000000)
{
P = (P << 1) / ((unsigned long int) var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
unsigned long int calibration_H(signed long int adc_H)
{
signed long int v_x1;
v_x1 = (t_fine – ((signed long int)76800));
v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) – (((signed long int)dig_H5) * v_x1)) +
((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
(((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
((signed long int) dig_H2) + 8192) >> 14));
v_x1 = (v_x1 – (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
return (unsigned long int)(v_x1 >> 12);
}
////////////////////////////////////////////////////////////////////////////
/*——– digitalClockDisplay code ———-*/
void digitalClockDisplay(){
// digital clock display of the time
strDate =strHH=strMM=strSS=””;
strDate+=year();
strDate+=”/”;
strDate+=month();
strDate+=”/”;
strDate+=day();
strDate+=” “;
inputDigit(hour()); // –> inputDigit() shown as below void function
strDate+=hour();
strDate+=”:”;
inputDigit(minute());
strDate+=minute();
strDate+=”:”;
inputDigit(second());
strDate+=second();
strHH+=hour();
strMM+=minute(); // 0,1,2,3….
strSS+=second(); // 0,1,2,3….
/*Serial.print(year());
Serial.print(“/”);
Serial.print(month());
Serial.print(“/”);
Serial.print(day());
Serial.print(” “);
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
*/
}
/*——– inputDigit code ———-*/
void inputDigit(int digits) {
if(digits < 10) {
//Serial.print(‘0’);
strDate+=”0″;
}
}
////////////////////////////////////////////////////////////
/*——– NTP code ———-*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println(“Transmit NTP Request”);
sendNTPpacket(timeServer);
uint32_t beginWait = millis();
while (millis() – beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println(“Receive NTP Response”);
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 – 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println(“No NTP Response :-(“);
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// 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)
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;
// 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();
}