顯示具有 Arduino mini 標籤的文章。 顯示所有文章
顯示具有 Arduino mini 標籤的文章。 顯示所有文章

讀取 Futaba 2.4G 接收機 Channel 信號..

Channel 4 (Rudder) "美國手"

Code:

unsigned long TransmitterThrottle=0;
unsigned long TransmitterCH4=0;

void setup()
{
Serial.begin(9600);

pinMode ( 9, INPUT);
pinMode (10, INPUT);

clearLCD();
}

void CheckTransmitter()
{
TransmitterThrottle = (pulseIn (9, HIGH, 200000))/10;
TransmitterCH4 = (pulseIn (10, HIGH, 200000));
}

void loop()
{
CheckTransmitter();

clearLCD (); // 清除 LCD 畫面
Serial.print ("pulse= ");
Serial.print (TransmitterThrottle, DEC);

Serial.print (" CH4: ");
Serial.print (TransmitterCH4, DEC );

delay(100);
}
// ===== clear the LCD =====
void clearLCD()
{
Serial.print(12, BYTE);
}

輸出數值:
中立: 1509 ~ 1514
至左: 1381 ~ 1388
至右: 1633 ~ 1639
要先搞清楚這些數值的 跳動 原因 ...

~ 待續 ~

讀取 Futaba 2.4G 接收機油門信號..

配件:
Futaba FF9 2.4G 發射器
Futaba R617FS 2.4G 接收器

Arduino Pin 9 連接 接收器 pin 3 信號
11.1V 鋰電 和 Arduino 共地 (GND)

執行結果:顯示數值
油門最低點 110
油門最高點 191





Code:

unsigned long TransmitterThrottle=0;

void setup()
{
pinMode (9, INPUT);

Serial.begin(57600);
Serial.println("System Ready~");
}

void CheckTransmitter()
{
TransmitterThrottle = (pulseIn (9, HIGH, 200000))/10;
}

void loop()
{
CheckTransmitter();
Serial.print ("pulse: ");
Serial.println (TransmitterThrottle);

delay (200);
}

Stepper motor 步進馬達的控制:

步進馬達的控制:
把老舊的 彩色印表機拆了,
發現裡面有一顆步進馬達,
使用 Arduino 接上馬達的4條線,
我使用了 pin 9~12,
輕易控制馬達前進後退和速度..

















Code:
#include

const int stepsPerRevolution = 100;

Stepper myStepper(stepsPerRevolution, 9,10,11,12);

void setup() {
myStepper.setSpeed(100);
Serial.begin(9600);
}

void loop() {
Serial.println("clockwise");
myStepper.step(stepsPerRevolution * 10);
delay(500);

Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution * 10 );
delay(500);
}


影片:

無刷馬達的控制..

在這個學習中使用了搖控直升機的 無刷馬達和電子變速器(ESC)
使用材料:
Align ESC BL15X
Align BL250 Brushless motor



















動作說明:
提升馬達速度, 降低馬達速度, 暫停..

Code:
#include

Servo myservo;

void setSpeed(int speed)
{
int val = map(speed, 0, 100, 0, 180);
myservo.write(val);
}
void setup()
{
Serial.begin(115200);
myservo.attach(9);
}
void loop()
{
Serial.println("System Ready !!! Hit the 1 ");
do{ if ( Serial.read() == '1' ) break; } while(1);


int speed;

Serial.println("Throttle up");
for(speed = 37; speed <= 90; speed += 1) { setSpeed(speed); Serial.println(speed); delay(100); } setSpeed(30); delay(1000); Serial.println("Throttle down"); for(speed = 90; speed > 37; speed -= 1) {
setSpeed(speed);
Serial.println(speed);
delay(100);
}
Serial.println("waiting for 5 sec...");
setSpeed(30);
delay(5000);
}

//=============================
另外也可以用程式..取代使用遙控器油門設定電變(ESC)的方式
例如電變的 緩啟動, 煞車模式, 截止電壓...等..
依照不同廠商生產不同的電變而有所差異..

Code:
// 程式設定ESC 狀態
void AdjustESC ()
{
//plug ESC Battery first, when ESC start music ready, enter "1" in serial window
Serial.println("Enter Setup Mode");
do{ if ( Serial.read() == '1' ) break;
setSpeed(90);
} while(1);
delay ( 2000 );
setSpeed(30);

// waiting for ESC edit mode music and into brake edit mode,
// then enter "1" in serial window
Serial.println("Break Mode - soft Brake");
do{ if ( Serial.read() == '1' ) break; } while(1);
setSpeed(50);


Serial.println("Electronic Timing -Mid timing");
do{ if ( Serial.read() == '1' ) break; } while(1);
setSpeed(50);


Serial.println("Battery Protection - High cut off voltage protection");
do{ if ( Serial.read() == '1' ) break; } while(1);
setSpeed(30);


Serial.println("Aircraft Mode - normal airplane");
do{ if ( Serial.read() == '1' ) break; } while(1);
setSpeed(30);


Serial.println("Throttle response speed - Quick speed");
do{ if ( Serial.read() == '1' ) break; } while(1);
setSpeed(90);


Serial.println("BEC output voltage - 5.5V");
do{ if ( Serial.read() == '1' ) break; } while(1);
setSpeed(50);

}

影片:

Wii Motion Plus

原文出處 http://randomhacksofboredom.blogspot.com/2009/06/wii-motion-plus-arduino-love.html
任天堂革命性的產品,
自己實作了一次,
這也算是窮人的陀螺儀吧..
//========= Arduino Code =========
#include <Wire.h>

byte data[6];    //six data bytes
int yaw, pitch, roll;  //three axes
int yaw0, pitch0, roll0;  //calibration zeroes
int startTag=0xDEAD;

void wmpOn(){
  Wire.beginTransmission(0x53);    //WM+ starts out deactivated at address 0x53
  Wire.send(0xfe);     //send 0x04 to address 0xFE to activate WM+
  Wire.send(0x04);
  Wire.endTransmission();    //WM+ jumps to address 0x52 and is now active
}

void wmpSendZero(){
  Wire.beginTransmission(0x52);    //now at address 0x52
  Wire.send(0x00);     //send zero to signal we want info
  Wire.endTransmission();
}

void calibrateZeroes(){
  for (int i=0;i<10;i++){
    wmpSendZero();
    Wire.requestFrom(0x52,6);
    for (int i=0;i<6;i++){
data[i]=Wire.receive();
    }
    yaw0+=(((data[3]>>2)<<8)+data[0])/10;  //average 10 readings for each zero
    pitch0+=(((data[4]>>2)<<8)+data[1])/10;
    roll0+=(((data[5]>>2)<<8)+data[2])/10;
  }
  /*Serial.print("Yaw0:");
  Serial.print(yaw0);
  Serial.print("  Pitch0:");
  Serial.print(pitch0);
  Serial.print("  Roll0:");
  Serial.println(roll0);*/
}

void receiveData(){
  wmpSendZero(); //send zero before each request (same as nunchuck)
  Wire.requestFrom(0x52,6);  //request the six bytes from the WM+
  for (int i=0;i<6;i++){
    data[i]=Wire.receive();
  }
  yaw=(((data[3]>>2)<<8)+data[0]);  //see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus
  pitch=(((data[4]>>2)<<8)+data[1]);    //for info on what each byte represents
  roll=(((data[5]>>2)<<8)+data[2]);
}

void setup(){
  Serial.begin(115200);
  //Serial.println("WM+ tester");
  Wire.begin();
  wmpOn(); //turn WM+ on
  calibrateZeroes();  //calibrate zeroes
  delay(1000);
}

void loop(){
  receiveData(); //receive data and calculate yaw pitch and roll
  Serial.write((unsigned byte*)&startTag, 2);  //see diagram on randomhacksofboredom.blogger.com
  Serial.write((unsigned byte*)&pitch0, 2);    //for info on which axis is which
  Serial.write((unsigned byte*)&yaw0, 2);
  Serial.write((unsigned byte*)&roll0, 2);
  Serial.write((unsigned byte*)&pitch, 2);
  Serial.write((unsigned byte*)&yaw, 2);
  Serial.write((unsigned byte*)&roll, 2);
  delay(10);
}
//================= End


//========= Processing Code =========
// 劃出波形

import processing.serial.*;

// Globals
int g_winW             = 820;   // Window Width
int g_winH             = 600;   // Window Height
boolean g_dumpToFile   = false;  // Dumps data to c:\\output.txt in a comma seperated format (easy to import into Excel)
boolean g_enableFilter = false;  // Enables simple filter to help smooth out data.

cDataArray pitch0    = new cDataArray(200);
cDataArray yaw0    = new cDataArray(200);
cDataArray roll0    = new cDataArray(200);
cDataArray pitch      = new cDataArray(200);
cDataArray yaw     = new cDataArray(200);
cDataArray roll     = new cDataArray(200);
cGraph g_graph         = new cGraph(10, 190, 800, 400);
Serial g_serial;
PFont  g_font;

void setup()
{
  size(g_winW, g_winH, P2D);

  println(Serial.list());
  g_serial = new Serial(this, "COM3", 115200, 'N', 8, 1.0);  //enter COM port of
  g_font = loadFont("AVGmdBU-30.vlw");                       //of arduino here
  textFont(g_font, 20);

  // This draws the graph key info
  strokeWeight(1.5);
  stroke(255, 0, 0);     line(20, 440, 35, 440);
  stroke(0, 255, 0);     line(20, 460, 35, 460);
  stroke(0, 0, 255);     line(20, 480, 35, 480);
  stroke(255, 0, 0);     line(20, 500, 35, 500);
  stroke(0, 255, 0);     line(20, 520, 35, 520);
  stroke(0, 0, 255);     line(20, 540, 35, 540);
  fill(0, 0, 0);
  text("pitch0", 40, 450);
  text("yaw0", 40, 470);
  text("roll0", 40, 490);
  text("pitch", 40, 510);
  text("yaw", 40, 530);
  text("roll", 40, 550);
  //text("current raw", 180, 430);
  //text("current deg/s", 320, 430);

  if (g_dumpToFile)
  {
    // This clears deletes the old file each time the app restarts
    byte[] tmpChars = {'\r', '\n'};
    saveBytes("c:\\output.txt", tmpChars);
  }
}

void draw()
{
  // We need to read in all the avilable data so graphing doesn't lag behind
  while (g_serial.available() >= 2*6+2)
  {
    processSerialData();
  }

  strokeWeight(1);
  fill(255, 255, 255);
  g_graph.drawGraphBox();

  strokeWeight(1.5);
  stroke(255, 0, 0);
  g_graph.drawLine(pitch0, 0, 16384);
  stroke(0, 255, 0);
  g_graph.drawLine(yaw0, 0, 16384);
  stroke(0, 0, 255);
  g_graph.drawLine(roll0, 0, 16384);
  stroke(255, 0, 0);
  g_graph.drawLine(pitch, 0, 16384);
  stroke(0, 255, 0);
  g_graph.drawLine(yaw, 0, 16384);
  stroke(0, 0, 255);
  g_graph.drawLine(roll, 0, 16384);
}

// This reads in one set of the data from the serial port
void processSerialData()
{
  int inByte = 0;
  int curMatchPos = 0;
  int[] intBuf = new int[2];

  intBuf[0] = 0xAD;
  intBuf[1] = 0xDE;

  while (g_serial.available() < 2); // Loop until we have enough bytes
  inByte = g_serial.read();

  // This while look looks for two bytes sent by the client 0xDEAD
  // This allows us to resync the server and client if they ever
  // loose sync.  In my testing I haven't seen them loose sync so
  // this could be removed if you need to, but it is a good way to
  // prevent catastrophic failure.
  while(curMatchPos < 2)
  {
    if (inByte == intBuf[curMatchPos])
    {
      ++curMatchPos;
     
      if (curMatchPos == 2)
        break;
   
      while (g_serial.available() < 2); // Loop until we have enough bytes
      inByte = g_serial.read();
    }
    else
    {
      if (curMatchPos == 0)
      {
        while (g_serial.available() < 2); // Loop until we have enough bytes
        inByte = g_serial.read();
      }
      else
      {
        curMatchPos = 0;
      }
    }
  }

  while (g_serial.available() < 2*6);  // Loop until we have a full set of data

  // This reads in one set of data
  {
    byte[] inBuf = new byte[2];
    int pitch0_cur, yaw0_cur, roll0_cur, pitch_cur, yaw_cur, roll_cur;

    g_serial.readBytes(inBuf);
    // Had to do some type conversion since Java doesn't support unsigned bytes
    pitch0_cur = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
    g_serial.readBytes(inBuf);
    yaw0_cur = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
    g_serial.readBytes(inBuf);
    roll0_cur = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
    g_serial.readBytes(inBuf);
    pitch_cur   = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
    g_serial.readBytes(inBuf);
    yaw_cur  = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
    g_serial.readBytes(inBuf);
    roll_cur  = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
   
    pitch0.addVal(pitch0_cur);
    yaw0.addVal(yaw0_cur);
    roll0.addVal(roll0_cur);
    pitch.addVal(pitch_cur);
    yaw.addVal(yaw_cur);
    roll.addVal(roll_cur);

    if (g_dumpToFile)  // Dump data to a file if needed
    {
      String tempStr;
      tempStr = pitch0_cur + "," + yaw0_cur + "," + roll0_cur + "," + pitch_cur + "," + yaw_cur + "," + roll_cur + "\r\n";
      FileWriter file;

      try 
      { 
        file = new FileWriter("c:\\output.txt", true); //bool tells to append
        file.write(tempStr, 0, tempStr.length()); //(string, start char, end char)
        file.close();
      } 
      catch(Exception e) 
      { 
        println("Error: Can't open file!");
      }
    }

    /*
    print(pitch0_cur);  print(" ");   print(yaw0_cur);   print(" ");    print(roll0_cur);     print(" ");
    print(pitch_cur);    print(" ");   print(yaw_cur);    print(" ");    println(roll_cur);
    */
  }
}

// This class helps mangage the arrays of data I need to keep around for graphing.
class cDataArray
{
  float[] m_data;
  int m_maxSize;
  int m_startIndex = 0;
  int m_endIndex = 0;
  int m_curSize;

  cDataArray(int maxSize)
  {
    m_maxSize = maxSize;
    m_data = new float[maxSize];
  }

  void addVal(float val)
  {
   
    if (g_enableFilter && (m_curSize != 0))
    {
      int indx;
     
      if (m_endIndex == 0)
        indx = m_maxSize-1;
      else
        indx = m_endIndex - 1;
     
      m_data[m_endIndex] = getVal(indx)*.5 + val*.5;
    }
    else
    {
      m_data[m_endIndex] = val;
    }
   
    m_endIndex = (m_endIndex+1)%m_maxSize;
    if (m_curSize == m_maxSize)
    {
      m_startIndex = (m_startIndex+1)%m_maxSize;
    }
    else
    {
      m_curSize++;
    }
  }

  float getVal(int index)
  {
    return m_data[(m_startIndex+index)%m_maxSize];
  }

  int getCurSize()
  {
    return m_curSize;
  }

  int getMaxSize()
  {
    return m_maxSize;
  }
}

// This class takes the data and helps graph it
class cGraph
{
  float m_gWidth, m_gHeight;
  float m_gLeft, m_gBottom, m_gRight, m_gTop;

  cGraph(float x, float y, float w, float h)
  {
    m_gWidth     = w;
    m_gHeight    = h;
    m_gLeft      = x;
    m_gBottom    = g_winH - y;
    m_gRight     = x + w;
    m_gTop       = g_winH - y - h;
  }

  void drawGraphBox()
  {
    stroke(0, 0, 0);
    rectMode(CORNERS);
    rect(m_gLeft, m_gBottom, m_gRight, m_gTop);
  }

  void drawLine(cDataArray data, float minRange, float maxRange)
  {
    float graphMultX = m_gWidth/data.getMaxSize();
    float graphMultY = m_gHeight/(maxRange-minRange);
   
    for(int i=0; i<data.getCurSize()-1; ++i)
    {
      float x0 = i*graphMultX+m_gLeft;
      float y0 = m_gBottom-((data.getVal(i)-minRange)*graphMultY);
      float x1 = (i+1)*graphMultX+m_gLeft;
      float y1 = m_gBottom-((data.getVal(i+1)-minRange)*graphMultY);
      line(x0, y0, x1, y1);
    }
  }
}
//================= End

RGB Led 1W

接線圖


















關鍵一:
Arduino Mini
腳位接到數位IO腳 3, 5, 6, 9, 10, 11 才能做輸出.. !!!
關鍵二:
此 RGB LED circuit 標示錯誤 - 負極..實際上要接 +正極,
R/G/B 接 Digital Pin, 共4線.. 不須接地線.

影片:



程式碼:
int R_ledPin = 9;

int G_ledPin = 10;

int B_ledPin = 11;

int ledPin = 13;



// val 255 = off

int R_val=254;

int G_val=254; 

int B_val=254;



void setup()

{ 

pinMode(ledPin, OUTPUT);



pinMode( R_ledPin, OUTPUT); 

pinMode( G_ledPin, OUTPUT); 

pinMode( B_ledPin, OUTPUT); 



Serial.begin ( 9600 );



analogWrite ( R_ledPin, R_val );

analogWrite ( G_ledPin, G_val );

analogWrite ( B_ledPin, B_val ); 



delay ( 1000 );

}

int dir=0;

int color = 0;

int offset = 5;

void loop() 

{

digitalWrite(ledPin, HIGH); 



switch ( color )

{

case 0: analogWrite ( R_ledPin, R_val ); break;

case 1: analogWrite ( G_ledPin, R_val ); break;

case 2: analogWrite ( B_ledPin, R_val ); break;

}



if ( dir == 0 )

{

if ( R_val - offset > 0 )

{

R_val -= offset;

}

else 

{

R_val = 0;

dir = 1; 

}

}



if ( dir == 1 )

{

if ( R_val + offset < 255 )

{ 

R_val += offset;

}

else 

{

R_val = 254;

dir = 0;



if ( color + 1 < 3 ) color ++;

else color = 0;

} 

}

//delay ( 300 );



clearLCD (); // 清除 LCD 畫面



// 輸出數值到 LCD

Serial.print ( "R= ");

Serial.print ( R_val, DEC );

Serial.print ( "\n");
}

// ===== clear the LCD =====

void clearLCD()
{
Serial.print(12, BYTE);

}

Part 4 - 控制 servo 轉動的速度, 而且要轉動的 Smooth

執行後是,左右轉到底再反向.


原始碼如下:
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 
void setup() 
{ 
  Serial.begin(9600);
  myservo.attach(9); 
} 
int pulse =2450;
int dir=1;
int offset=1;
void loop() 
{
  myservo.writeMicroseconds( pulse );
  if ( pulse + offset >= 2450 ) dir = -1;
  else if ( pulse - offset <= 600 ) dir = 1;
  
  pulse += ( offset * dir);

  Serial.println ( pulse, DEC );
}

arduino Mini 的學習之路..( Part -3 )



課目: 伺服馬達的控制  ( PWM )

Hitec HSR-8498HB 伺服馬達 ( 腳位接線圖 )

我這個實驗使用的是 Hitec HSR-8498HB 伺服馬達.
目前使用驅動模式選擇第一種已經成功.
這個馬達總共有3種模式,
1. Standard Pulse Mode (Pulse width 550 to 2450 Microseconds)
角度計算式 Servo Angle (degrees) = (Pulse Width (•S) – 1500) / 10

2. Extended Pulse Mode. (Pulse width 50 to 200 Microseconds) (未完成)

3. Serial Mode. (Pulse width 416 Microseconds) (未完成)

馬達的說明文件連結:
http://robosavvy.com/Builders/i-Bot/HSR8498HB%20Servo.pdf


^^ 上面影片的程式範例:

#include <Servo.h>

Servo myservo; // create servo object to control a servo

void setup()
{
Serial.begin( 19200 );
myservo.attach(9); //連接 Servo 信號到 Digital Pin 9
}

int angleVal=550;

void loop()
{
myservo.writeMicroseconds( angleVal ); //Pulse width 550 to 2450 Microseconds = Standard Pulse Mode

if ( angleVal + 100 <= 2450 )
{
angleVal += 100;
delay ( 1000 );
}
else angleVal = 550;

delay ( 300 );

int readdata=0;

readdata = myservo.read ();

Serial.println ( readdata );

}

arduino Mini 的學習之路..( Part -2 )


看了網頁上的一些前輩教學,( http://accrochages.drone.ws/en/node/90 )

接續我的 Arduino Part -1 ,

應用了 Processing 實現了圖形化的數據顯示,

因為開始複雜化了.. 2 x 16 LCD 不敷使用了

上面的曲線就是光敏電阻傳回來的數值.

接下來 Project 越來越精彩了... 敬請期待~

arduino Mini 的學習之路..( Part -1 )


使用 Mini USB 供應 5V電壓.
16 x 2 LCD 顯示 光敏電阻的數值.



 



 

~~ 安裝教學 Step By Step ~~

1. 先安裝電腦 Driver:

Download USBtoTTL Driver "CDM20600.exe",

下載連結 http://www.ftdichip.com/Drivers/VCP.htm

2. 將USB線插入電腦:

這時候打開工作管理員,

確認 COM PORT 的使用和驅動無誤( 使用的 PORT依情況會不同 ),

3. 執行 Arduino 0018:

設定 Tools->Board ( Arduino Mini )

設定 Tools->Serial Port ( COM 3)

4. 光感測器接線:
黑 - GND
紅 - 5V
白 - 信號 ( 接到 Arduino 的 digital pin 0 )
5. Parallax LCD接線:
GND
5V
RX  (接到 Arduino 的 TX)

~~ 使用材料 ~~
1. Arduino Mini.
2. USBtoTTL Board.
3. USB Cable.
4. 光感測器
5. LED
6. 麵包板.
7. Parallax LCD

// 程式碼 //
int ledPin = 13; // LED connected to digital pin 13
int PhotoSPin = 0; // Photosensitive connected to digital pin 0
int Analog_val =0; // Photosensitive Val

void setup()
{
    Serial.begin ( 9600 );

    pinMode(ledPin, OUTPUT); // LED
    pinMode(PhotoSPin, INPUT); // Photosensitive
}

void loop()
{
digitalWrite(ledPin, HIGH); // set the LED on
delay(Analog_val); // wait for a second
digitalWrite(ledPin, LOW); // set the LED off
delay(Analog_val); // wait for a second

Analog_val = analogRead(PhotoSPin); //讀取 光敏電阻 的數值

clearLCD (); // 清除 LCD 畫面

//===== 輸出數值到 LCD =====
Serial.print ( "Val= ");
Serial.print ( Analog_val, DEC );
Serial.print ( "\n");
}
// ===== clear the LCD =====
void clearLCD()
{
    Serial.print(12, BYTE);
}