Introduction: Hunchback Alarm

目前使用手機或電腦造成所謂低頭族的現象,會對頸椎或腰椎有很大負擔。但即使知道,在日常生活中還是會不自覺駝背,所以我要做一個簡單的小裝置提醒人,坐著的時候不要駝背。

Step 1: Materials

器材:

  1. 汽車天線BF-686(升降用)
  2. SG-90伺服馬達
  3. HC-SR04超音波測距
  4. 喇叭
  5. 連接線
  6. 膠水
  7. 微動開關
  8. 繼電器

Step 2: 組裝

  1. 將SG-90馬達黏在天線頂端,用AB膠。注意固定時間可能不能太短。要確保穩定。
  2. 製作SG-90和HC-SR04的連接線。因為天線會往上,所以要夠長,避免上升過程中拉斷。
  3. BF-686天線原理是紅綠給正電會往上,只有紅線給電就會下降,需要用兩個relay來控制天線升降或停止
  4. 將HC-SR04固定在SG-90馬達上,注意轉動範圍,要讓超音波可以對到頭腦的可能位置。
  5. 將天線固定在椅子上。

Step 3: Arduino Code

#define arrayLength 6

//const int debounceDelay=20; const int SW1=2; const int SW2=3; const int relay1=4; const int relay2=5; const int speaker=12; boolean stateSW1; boolean stateSW2;

const int SW3=10; const int SW4=11; boolean stateSW3; boolean stateSW4; int reporter=0;

int checkPoint[arrayLength]={0}; // each=2, boolean=1 int distance[arrayLength]={0}; // each=2 const byte init_distance=40; float critical_distance=0; float real_distance=0; void cleanArray(int ARRAY[]);

/* fot Serial monitor input, choose "Both NL & NR" or "Newline" to make it working normally. */ #include Servo myservo; // create servo object to control a servo byte pos = 90; // variable to store the servo position byte horizontalPos = 90; //String comdata = "";

#include #define TRIGGER_PIN 6 #define ECHO_PIN 7

Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);

void setup() { Serial.begin(9600); pinMode(relay1,OUTPUT); pinMode(relay2,OUTPUT); pinMode(SW1,INPUT_PULLUP); pinMode(SW2,INPUT_PULLUP); tone(speaker,523,1000); //check digitalWrite(relay1, LOW); digitalWrite(relay2, HIGH); delay(2000); //position reset tone(speaker,554,1000); //check digitalWrite(relay1, HIGH); myservo.attach(8); // attaches the servo on pin 9 to the servo object pinMode(SW3,INPUT_PULLUP); pinMode(SW4,INPUT_PULLUP); }

void loop() {//printArray(checkPoint); if(checkPoint[0]==0){ myservo.write(pos); stateSW3=digitalRead(SW3); stateSW4=digitalRead(SW4); delay(200); //不然按一下噴很多 if(stateSW3==LOW && stateSW4==HIGH){ pos+=5; }else if(stateSW3==HIGH && stateSW4==LOW){ pos-=5; } if(pos<0||pos>180){ Serial.println("out of range"); pos=90; } Serial.println(pos); stateSW1=digitalRead(SW1); if(stateSW1==LOW){ horizontalPos=pos; myservo.write(horizontalPos); cleanArray(checkPoint); checkPoint[0]=1; } //user choose whcih angle is horizontal position. I am not sure whether variable horizontalPos necessary?? }else if(checkPoint[1]==0){ // printArray(checkPoint); while(compareArray(distance,-1,init_distance)==-99 && checkPoint[2]==0) //把陣列塞滿實際偵測數值 { accumulateArray(); // Serial.println(millis()); } checkPoint[2]=1; // printArray(checkPoint); // delay(1000); while(compareArray(distance,-1,init_distance)==0 && checkPoint[3]==0) //小於20cm就往上 { accumulateArray(); digitalWrite(relay1, LOW); digitalWrite(relay2, LOW); } checkPoint[3]=1; // printArray(checkPoint); delay(500); //再往上一點點 digitalWrite(relay1, HIGH); digitalWrite(relay2, HIGH);

while(compareArray(distance,-1,init_distance)!=0 && checkPoint[4]==0) { accumulateArray(); digitalWrite(relay1, LOW); digitalWrite(relay2, HIGH); } checkPoint[4]=1; delay(500); digitalWrite(relay1, HIGH); digitalWrite(relay2, HIGH); checkPoint[1]=1; // printArray(checkPoint); }else if(checkPoint[5]==0){ critical_distance=avgArray(distance); checkPoint[5]=1; }else{ stateSW1=digitalRead(SW1); //只重設高度,不重新校正水平,須改用中斷 if(stateSW1==LOW){ cleanArray(distance); cleanArray(checkPoint); checkPoint[0]=1; } printArray(distance); accumulateArray(); real_distance=avgArray(distance); delay(200); int diff_distance=(real_distance-30)/5; Serial.println(real_distance); Serial.println(critical_distance); Serial.println(diff_distance); Serial.println(500-diff_distance*50); if(diff_distance<3) diff_distance=0; switch(diff_distance){ case 0: break; case 3: tone(speaker,880,500); delay(500); break; case 4: tone(speaker,880,400); delay(400); break; case 5: tone(speaker,880,300); delay(300); break; case 6: tone(speaker,880,200); delay(200); break; case 7: tone(speaker,880,100); delay(100); break; default: tone(speaker,880,50); break; } } }

void cleanArray(int ARRAY[]){ for(int i=0;i0;i--){ ARRAY[i]=ARRAY[i-1]; } } int compareArray(int ARRAY[],int indicator,int value){ int messanger=0; for(int i=arrayLength-1;i>=0;i--){ if(ARRAY[i]==0){ Serial.println("compareArray step0"); return -99; } } switch (indicator){ case -1: for(int i=arrayLength-1;i>=0;i--){ if(ARRAY[i]>=value) messanger+=3; } // Serial.println("compareArray step1"); return messanger; break; case 0: for(int i=arrayLength-1;i>=0;i--){ if(ARRAY[i]==value) messanger+=100; } Serial.println("compareArray step2"); return messanger; break; case 1: for(int i=arrayLength-1;i>=0;i--){ if(ARRAY[i]<=value) messanger-=13; } Serial.println("compareArray step3"); return messanger; break; default: Serial.println("all right! what's going on???"); } } float US(){ float cmMsec; long microsec = ultrasonic.timing(); cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); return cmMsec; } void accumulateArray(){ float D=US(); shiftArray(distance); distance[0]=D; // printArray(distance); } float avgArray(int ARRAY[]){ int s=0; for(int i=0;i

Step 4: 啟動:調整HC-04超音波感測,使其垂直地面

  1. arduino 啟動後,使用sw3 sw4控制角度。
  2. 人坐定,抬背挺胸,SW1確認後會自動偵測身高,停在頭部位置。
  3. 如果駝背往前距離拉長,就會有警報聲。