// // アナログ気圧計 // MPL115A2の値を読んでアナログ時計の短針を使って気圧を表示。 // MPL115A2の制御はgarretlabさん作成の関数を使用しています。 // by ラジオペンチ http://radiopench.blog96.fc2.com/ // 2013/12/14 初版作成 // // スケッチサイズ7780バイト #include // 気圧計関係の変数 const int addresPsensor = 0x60; // 気圧計のI2Cアドレス float a0, b1, b2, c12, c11, c22; float Pha; unsigned int Padc; unsigned int Tadc; long lastPressValue; boolean flag = false; // モータ励磁方向フラグ unsigned int cwPulse = 17; // 順回転パルス幅 標準は17mS unsigned int ccwPulse1 = 3500; // 逆回転パルス幅1 単位はus unsigned int ccwPulse2 = 12000; // 逆回転パルス幅2 単位はus,値の上限は16383 void setup(){ // pinMode(9, OUTPUT); // conect coil thrugh 220Ω pinMode(10, OUTPUT); // coil return pinMode(13, OUTPUT); // 動作表示LED Wire.begin(); Serial.begin(9600); Serial.println("Balometer start"); delay(1000); // 気圧計が立ち上がるまで待つ readCalConst(); // 校正係数読み出し lastPressValue=Psens(); // 初期気圧測定 Serial.print("initial value = "); Serial.println(lastPressValue); Serial.println(""); } // setup void loop(){ // メインループ long x = Psens(); // 気圧測定 単位:0.01hPa moveTo(x); // 針を気圧の位置に動かす delay(60000); // サイクルタイム } // Loop void readCalConst(){ // 気圧計校正係数読み出し Wire.beginTransmission(addresPsensor); Wire.write(0x04); // Read coefficient data Wire.endTransmission(); Wire.requestFrom(addresPsensor, 12); // Request 12 bytes if (Wire.available()) { a0 = read_coefficients(16, 3, 0); b1 = read_coefficients(16, 13, 0); b2 = read_coefficients(16, 14, 0); c12 = read_coefficients(14, 13, 9); c11 = read_coefficients(11, 10, 11); c22 = read_coefficients(11, 10, 15); } /* Serial.println("1000 * coefficient a0, b1, b2, c12, c11, c22 "); Serial.print(a0*1000); Serial.print(", "); Serial.print(b1*1000); Serial.print(", "); Serial.print(b2*1000); Serial.print(", "); Serial.print(c12*1000); Serial.print(", "); Serial.print(c11*1000); Serial.print(", "); Serial.println(c22*1000); */ } long Psens(){ // 気圧読み出し float sumP; long outP; int n; sumP = 0; for(n=0; n<1000; n++){ // バラツキが大きいので1000回アベレージング sensData(); // 気圧計のデータを読む(本番) sumP = sumP + Pha; } outP = sumP/10; // 0.01hPa単位の整数に変換 return outP; } // Psens void sensData () { // センサーから値を読み出す Wire.beginTransmission(addresPsensor); Wire.write(0x12); // Start both conversions(Pressure and Temperature) Wire.write(0x01); Wire.endTransmission(); delay(3); Wire.beginTransmission(addresPsensor); Wire.write((uint8_t)0x00); // Read pressure and temperature Wire.endTransmission(); Wire.requestFrom(addresPsensor, 4); // Request 4 bytes if(Wire.available()) { Padc = read_adc(); Tadc = read_adc(); int signedTadc = Tadc; // float Pcomp = a0 + (b1 + c11 * Padc + c12 * Tadc) * Padc + (b2 + c22 * Tadc) * Tadc; // 22976 float Pcomp = a0 + (b1 + c12 * Tadc) * Padc + (b2 * Tadc); // c11 とc22はゼロなので計算省略(84バイト節約) Pha = Pcomp * 650 / 1023 + 500; // 気圧の値をヘクトパスカルに換算 } delay(1); } // sensData float read_coefficients(int total_bits, int fractional_bits, int zero_pad) { unsigned char msb, lsb; msb = Wire.read(); lsb = Wire.read(); Serial.print("mbs = "); Serial.print(msb); Serial.print(", lsb = "); Serial.println(lsb); return ((float) ((msb << 8) + lsb) / ((long)1 << (16 - total_bits + fractional_bits + zero_pad))); } // read_coefficient unsigned int read_adc() { unsigned char msb, lsb; msb = Wire.read(); lsb = Wire.read(); return (((unsigned int)msb << 8) + lsb) >> 6; } // read_adc void moveTo(long x){ // 指定した気圧の位置に針を動かす static int lastMod; long y,p; y = x - lastPressValue; // 気圧変化量 単位:0.01hPa p = (y * 6 + lastMod) / 10; // ドライブパルス量は yの0.6倍 lastMod = ( y * 6 + lastMod) % 10; // 余りは次回の計算のために保存 Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", "); Serial.print(p); Serial.print(", "); Serial.println(lastMod); clockDrive(p); // 針を動かす lastPressValue = x; // 気圧の値を保存 } // moveTo void clockDrive(int x){ // 引数の値だけ針を動かす if( x != 0){ if( x > 0){ cw(x); } else{ x *= -1; ccw(x); } } } // clockDrive void cw(int n){ // 指定パルスだけ順回転 if(n !=0){ for(int x = 1; x <=n; x++){ cwP(); delay(35); // 順回転速度設定(MAXは25程度) } } } //cw void ccw(int n){ // 指定パルスだけ逆回転 if(n !=0){ for(int x = 1; x <=n; x++){ ccwP(); delay(60); // 逆回転速度設定(MAXは50程度) } } } //ccw void cwP(){ // 順回転パルス発生 digitalWrite(13,HIGH); // LED flash flag = ! flag; if (flag == true) { digitalWrite(9, HIGH); // coil drive foward delay(cwPulse); // wait digitalWrite(9, LOW); // coil drive end } else { digitalWrite(10, HIGH); // coil drive revers delay(cwPulse); // wait digitalWrite(10, LOW); // coil drive end } digitalWrite(13,LOW); // LED flash end } //cwP void ccwP(){ // 逆回転パルス発生 digitalWrite(13,HIGH); // LED flash flag = ! flag; if (flag == true) { digitalWrite(9, HIGH); // coil drive foward delayMicroseconds(ccwPulse1); // wait digitalWrite(9, LOW); // coil drive end digitalWrite(10, HIGH); // coil drive revers delayMicroseconds(ccwPulse2); // wait digitalWrite(10, LOW); // coil drive end } else { digitalWrite(10, HIGH); // coil drive revers delayMicroseconds(ccwPulse1); // wait digitalWrite(10, LOW); // coil drive end digitalWrite(9, HIGH); // coil drive foward delayMicroseconds(ccwPulse2); // wait digitalWrite(9, LOW); // coil drive end } digitalWrite(13,LOW); // LED flash end } //ccwP