2017年12月29日 星期五

建立360度旋轉物品的影像

 之前看到有一款,可以將物品放在一個平台上,平台會旋轉同時讓相機拍照。然後再把相片串起來變成可以360旋轉的影像。當時就想,這玩意兒應該不難作。昨天終於下定決心要把這個東西做出來。

要讓東西旋轉很簡單,就用伺服馬達就行,但是SG90伺服馬達只能轉180度,如果要360度的話就要連續旋轉伺服馬達(SG35)。不過這個東西要控角度很麻煩,也是讓我花最多時間的地方。

要讓手機拍照的話,就要用手機快門線來控制了。原理部分,雄哥說的很清楚,這邊不用重複了。不過因為我有買便宜的自拍棒,放著好幾年都沒用(根本沒在自拍啊啊啊啊啊),所以就決定拆了自拍棒的快門線來改。


這玩意兒就是自拍棒,把3.5mm的耳機頭插入手機耳機孔之後,按下按鈕就可以拍照。按鈕的功能,就是把其中兩個金屬接點連通,所以我只要用arduino控制繼電器,用繼電器控制金屬接點是否連通就可以控制拍照了。



那麼接下來就先剝皮~不是太貴的東西,很容易拆!

線拔下來之後(拆斷了,再焊回去)就長這樣子,右邊的電路板中間圓形金色的部分就是按鈕。其實是一個有彈性的圓形金屬片,按下去金屬片就接觸下面的接點。放手之後就會彈回來這樣。

圓形金屬片周圍有四個裸露的接點,上下一接通,手機就拍照。所以我只要把兩個接點再各自焊上一條線和繼電器連接就行了。



焊好了,焊工很爛,這種小小的接點和不太愛吃焊錫的線真是辛苦我了。

實際的外觀和運作的效果就來看影片好了




接著利用webrotate360的程式來製作360相片。實際製作之前最好把照片縮圖一下,不然電腦loading很大,跑不動。


最後做出來的gif檔如下圖。webrotate360還可以把檔案輸出,變成互動式的360旋轉檔案。也就是可以在電腦上用滑鼠或平板上用手指控制旋轉方向。我有在Windows的電腦上,用IE看到preview的檔案,但還不知道怎樣上傳到網路上,或是嵌入在blogger裡面。

調校的過程中,最花時間的是調整伺服馬達的轉速和拍攝張數。也就是以某個轉速到底轉一圈會停多少次,然後多少張畫面拍起來才有連續的效果。這些都花了不少時間測試。
via GIPHY



以下是程式碼
//連續旋轉伺服馬達製作360 camera with iPhone


#include <LiquidCrystal_I2C.h>
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // 設定 LCD I2C 位址
//以上是驅動LCD的部分

#include <Servo.h>
#define relayPin 8
#define starter 2
int speeder;
int statue=0;
int photos=0;
int VR;
int relayStatue;
Servo servoH;
int s=0;
int time;
void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode (relayPin, OUTPUT);
  pinMode (starter, INPUT);
  servoH.attach(7);
  digitalWrite(relayPin,HIGH);
  lcd.setCursor(0,0);
  lcd.print("press 2 to start");
}

void loop()
{
  speeder = map(VR, 0, 1024, 1, 4);
  lcd.setCursor(0,1);
  lcd.print("speed=");
  lcd.print(speeder);
  VR=analogRead(0);
  float speeder2;
  Serial.print(speeder2);
  Serial.print(",");
  Serial.print(photos);
  Serial.print(",");
  Serial.println(s);
if(speeder ==1){
  speeder2 = 97;
  photos=240;
}

if(speeder ==2){
  speeder2 = 98;
  photos=91;
}

if(speeder ==3){
  speeder2 = 100;
  photos=35;
}
  speeder=analogRead(0)/128;
  if (digitalRead(starter) == 0){
    statue = statue +1;
    delay(300);
  }
 
  if (statue ==1){
  if(s < photos) {
  servoH.write(speeder2);
  digitalWrite(relayPin, HIGH);
  delay(200);
  servoH.write(95);
  digitalWrite(relayPin, LOW);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("photos left=");
  lcd.print(photos-s);
  delay(800);
  s=s+1;
    }
    else {
      servoH.write(95);
      digitalWrite(relayPin,HIGH);
      lcd.clear();
      lcd.print("completed");
      delay(1000);
      statue=0;
      s=0;
      photos=0;
      lcd.setCursor(0,0);
      lcd.print("press 2 to start");
    }
}
if (statue == 2){
  servoH.write(95);
  statue = 0;
  s=0;
  photos=0;
}
}

沒有留言: