6 Eylül 2017 Çarşamba

Ardunio VirtualWire ve ServoTİmer2 kullanımı

Kızımın uzaktan kumandalı arabasının alıcı kartı yandı araç kullanılamaz durumdaydı. Aracın orjinalinde hız tek devirdi aynı şekilde sağa ve sola dönüşlerde tek kademeydi bende ardunio uno , motor shield, joystick, servo, 433mhz alıcı verici alarak aracı baştan yapmaya karar verdim.

Karşılaştığım tek sorun ve en büyük sorun servo.h kütüphanesinin Virtualwire ile birlikte kullanılamaması oldu bu iki kütüphanede aynı timer'ı kullandığı için derleme hatası veriyordu

İnternette günlerce araştırma yaptım bulduğum örnekleri denedim fakat her zaman olduğu gibi bizim tipik Türk Halkı copy&paste yaptığı makaleleri paylaşıp durmuşlar hiçbiri çalışmıyor.

ServoTimer2 kütüphanesini araştırdım fakat onda da birkaç yerde aksilikler çıktı. en son yabancı bir sitede bir örnek buldum o örnek çalıştı.aynı örneği alıp kendi koduma uyarladığımda kod çalışmayınca servo.h ile ServoTimer2 arasında bir timerdan daha fazla fark olduğunu düşündüm ve çalışan örnekte satırlar arasına serial monitör kodlarını yerleştirip neler olduğunu anlamaya çalıştım ve sorunun ne olduğu ortaya çıktı. İnternetteki copy paste ci arkadaşların kodunun çalışma şansının hiç olmadığını daha iyi anladım.

Servo.h kütüphanesinde servo açısını direk belirterek servonun gideceği noktayı belirliyorduk fakat ServoTimer2 de durum farklı 180 derece 544 ile 2400 arası değer aralığınla ifade edilmekte.Yani 0 derece için 0 değil myservo.write(544); yazmak gerekiyor. ayrıca ServoTimer2.h kütüphanesindeki satırlarda ufak bir değişiklik gerekiyor.

typedef uint8_t boolean; ve typedef uint8_t byte; satırlarının başına // işareti koyarak kapatmamız gerekiyor. yoksa aynı değişkenler ardunio.h dosyasında da tanımlandığı için hata vermekte.



Araç için kullandığım kodları aşağıda ki linklerden bulabilirsiniz. Verici kodu olduğu gibi kullandım alıcı kodunu kendime göre eklemeler yaptım. Servo yoktu mesela bu kodda servo ekledim.

Alıcı Kodu:
#include
// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
#include
#include
ServoTimer2 yonservo;
//AF_DCMotor motor1(1, MOTOR12_1KHZ); // create motor #1, 1KHz pwm
//AF_DCMotor motor2(2, MOTOR12_1KHZ); // create motor #2, 1KHz pwm
//AF_DCMotor motor3(3, MOTOR34_1KHZ); // create motor #3, 1KHz pwm
AF_DCMotor motor4(4, MOTOR34_1KHZ); // create motor #4, 1KHz pwm

//const int X_THRESHOLD_LOW = 505;
//const int X_THRESHOLD_HIGH = 530;    

//const int Y_THRESHOLD_LOW = 500;
//const int Y_THRESHOLD_HIGH = 510;    

int x_position;
int y_position;
int servoaci = 802;
int x_direction;
int y_direction;

int current_x_direction;
int current_y_direction;

uint8_t motor4_speed;

void setup()
{
    Serial.begin(9600); // Debugging only
    Serial.println("setup");
   motor4_speed = 255;
   yonservo.attach(10);
    
   
yonservo.write(servoaci);
    motor4.setSpeed(0);     // set the speed to 200/255
    motor4.run(RELEASE);      // turn it on going backwards         

    // Due to lack of access to Digital Pins with Motor Shield in place, using Analogue A0 (Arduino Pin 14) as Digital
    vw_set_rx_pin(14);
    
    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);  // Bits per sec

   vw_rx_start();       // Start the receiver PLL running

  //  current_x_direction = 0;
  //  current_y_direction = 0;
    x_direction = 0;
    y_direction = 0;
    Serial.println("setup done");
}

void loop()
{
  
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;


   if (vw_get_message(buf, &buflen)) // Non-blocking
    {
        int i;
      
        digitalWrite(13, true); // Flash a light to show received good message
// Message with a good checksum received, dump it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
    Serial.print(buf[i], HEX);
    Serial.print(" ");
}
Serial.println("");
        digitalWrite(13, false);

      // Format is XnnnnYnnnnAnBnCnDn
      // X is X position of joystick as 4 digits
      // Y is Y position of joystick as 4 digits
      // A is A button on joystick. 0= Not pressed. 1 = pressed
      // B is B button on joystick. 0= Not pressed. 1 = pressed
      // C is C button on joystick. 0= Not pressed. 1 = pressed
      // D is D button on joystick. 0= Not pressed. 1 = pressed

      //Serial.println("");

      y_position = (1000 * (buf[1] - 48)) + (100*(buf[2] - 48)) + (10*(buf[3] - 48)) + (buf[4] - 48);
      x_position = (1000 * (buf[6] - 48)) + (100*(buf[7] - 48)) + (10*(buf[8] - 48)) + (buf[9] - 48);

      Serial.println(x_position);
      Serial.println(y_position);
     
          //ileri
       if (x_position > 600){
        x_direction = 1;
        motor4_speed = map(x_position,550,1023,0,255);
        Serial.println("ileri");
      }
          // Geri
      else if (x_position < 400){
        x_direction = -1;
        motor4_speed = map(x_position,450,0,0,255);
        Serial.println("Geri");
      }
      // Dur
      else {
        x_direction = 0;
          motor4_speed = 0;
        Serial.println("Dur"); 
      }
    
   

      if ((y_position > 450) && (y_position < 550))
      {
        servoaci=802;
        Serial.println("Orta");
      }

   else if ((y_position < 450) || (y_position > 550)) 
       {
         servoaci = map(y_position,0,1023,544,1059);
       // Serial.println("Sol");
      }


     
         motor4.setSpeed(motor4_speed);     
          
//delay(10);
         
if (x_direction==1)
{  
   motor4.run(FORWARD);
   yonservo.write(servoaci); 
   delay(100);
}

          
 else if(x_direction==-1)
      {
          motor4.run(BACKWARD); 
          yonservo.write(servoaci);
          delay(100);
      }   
               

 else if(x_direction==0)
      {
          motor4.run(RELEASE); 
          yonservo.write(servoaci);
          delay(100);
      }

    }     
   
 Serial.println(yonservo.read());   
 Serial.println(y_position);

}

Verici Kodu
// transmitter.pde

#include <VirtualWire.h>
// Store the Arduino pin associated with each input
// Select button is triggered when joystick is pressed
const byte PIN_BUTTON_SELECT = 2;
const byte PIN_BUTTON_RIGHT = 3;
const byte PIN_BUTTON_UP = 4;
const byte PIN_BUTTON_DOWN = 5;
const byte PIN_BUTTON_LEFT = 6;
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
int x_position;
int y_position;
char msg[19]="X0000Y0000A0B0C0D0";
int led = 13;
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
Serial.println("setup");
pinMode(PIN_BUTTON_RIGHT, INPUT);
digitalWrite(PIN_BUTTON_RIGHT, HIGH);
pinMode(PIN_BUTTON_LEFT, INPUT);
digitalWrite(PIN_BUTTON_LEFT, HIGH);
pinMode(PIN_BUTTON_UP, INPUT);
digitalWrite(PIN_BUTTON_UP, HIGH);
pinMode(PIN_BUTTON_DOWN, INPUT);
digitalWrite(PIN_BUTTON_DOWN, HIGH);
pinMode(PIN_BUTTON_SELECT, INPUT);
digitalWrite(PIN_BUTTON_SELECT, HIGH);
// VirtualWire Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
}
void loop() {
int thous;
int huns;
int tens;
int ones;
char digitsascii[5] = "0000";
x_position = analogRead(PIN_ANALOG_X);
y_position = analogRead(PIN_ANALOG_Y);
// Format is XnnnnYnnnnAnBnCnDn
// X is X position of joystick as 4 digits
// Y is Y position of joystick as 4 digits
// A is A button on joystick. 0= Not pressed. 1 = pressed
// B is B button on joystick. 0= Not pressed. 1 = pressed
// C is C button on joystick. 0= Not pressed. 1 = pressed
// D is D button on joystick. 0= Not pressed. 1 = pressed
//First convert X pos to 4 ascii characters (48 is decimal ASCII code for '0')
thous = x_position/1000;
msg[1]=thous+48;
huns = (x_position - (thous*1000))/100;
msg[2]=huns+48;
tens = (x_position - (thous*1000) - (huns*100))/10;
msg[3]=tens+48;
ones = x_position - (thous*1000) - (huns*100) - (tens*10);
msg[4]=ones+48;
//Then convert Y pos to 4 ascii characters
thous = y_position/1000;
msg[6]=thous+48;
huns = (y_position - (thous*1000))/100;
msg[7]=huns+48;
tens = (y_position - (thous*1000) - (huns*100))/10;
msg[8]=tens+48;
ones = y_position - (thous*1000) - (huns*100) - (tens*10);
msg[9]=ones+48;
// Will implement buttons laters
digitalWrite(led, HIGH);
Serial.println(msg);
// send string to receiver (actually just broadcast. No concept of 1-1 comms with these TX/RX modules
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx(); // Wait until the whole message is gone
delay(100);
digitalWrite(led, LOW);
delay(100);
}