/* 変な動きの時計 Pin9-10:220Ω経由で時計のコイル Pin8は動作モード。  最初にLowで秒針送り。Highで秒針停止させて位置合わせ。  再度Lowで運転開始する。 2013/11/16 ラジオペンチ http://radiopench.blog96.fc2.com/ */ #include boolean flag = false; volatile boolean pps = false; unsigned int cwPulse = 17; // 順回転パルス幅 標準は17mS unsigned int ccwPulse1 = 3500; // 逆回転パルス幅1 unsigned int ccwPulse2 = 12000; // 逆回転パルス幅2(値の上限は16383) unsigned long timeNow, dispLast; // 32ビットあれば100年以上大丈夫 int drivePulse, offset; void setup() { pinMode(13, OUTPUT); pinMode(9, OUTPUT); // conect coil thrugh 220Ω pinMode(10, OUTPUT); // coil return pinMode(8, INPUT); // 秒針合わせスイッチ digitalWrite(8, HIGH); // weak pull up pin 8 while(digitalRead(8)==LOW){ // 8ピンがLOWの間は cwP(); // 順回転させて秒針の位置あわせ delay(500); } while(digitalRead(8)==HIGH){ // 8ピンが再びLOWになるまで待って動作開始 } randomSeed(micros()); // 乱数の種を仕込む MsTimer2::set(1000, oneSecond); // 1秒毎に割り込み MsTimer2::start(); } void loop() { while(pps == false){ // 割り込みでppsがTRUEになるまで待つ } pps = false; // すぐにフラグを倒し timeNow++; // 現在時刻を進め offset=getOffset(); // オフセット値を決め drivePulse = timeNow + offset -dispLast; // 送りパルス数を計算して clockDrive(drivePulse); // 針を動かす。 dispLast = timeNow + offset; // 次回のために針の位置を記録 } int getOffset(){ // オフセットをランダムに決める int x, y; x = timeNow % 60; if((x <= 5) || (x >= 55)){ // 秒針が正時付近なら y = 0; // 真面目にやる } else{ // 正時付近以外なら乱数入れる y = random(0, 7) - 3; } return y; } void clockDrive(int x){ // 引数の値だけ針を動かす if( x != 0){ if( x > 0){ cw(x); } else{ x *= -1; ccw(x); } } } void cw(int n){ // 指定パルスだけ順回転 if(n !=0){ for(int x = 1; x <=n; x++){ cwP(); delay(25); // 順回転速度設定 } } } void ccw(int n){ // 指定パルスだけ逆回転 if(n !=0){ for(int x = 1; x <=n; x++){ ccwP(); delay(50); // 逆回転速度設定 } } } 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 } 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 } void oneSecond() { // MsTimer2の割り込み処理 pps = true; // ppsフラグをアサート }