конфликт библиотек VirtualWire.h и Servo.h

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Собственно хотелось попробовать поковырятся с радио управлением на таких простейших модулях 433Mhz . За основу хотел взял этот пример, но как только добавляю в него Servo.h
происходит ошибка компиляции.(без библиотеки Servo.h пример работает)
Буду признателен за любые советы , и просто размышления по теме.

Вот такая ошибка выдаётся:

VirtualWire\VirtualWire.cpp.o: In function `__vector_11':

D:\arduino\arduino-1.0.5\libraries\VirtualWire/VirtualWire.cpp:568: multiple definition of `__vector_11'
Servo\Servo.cpp.o:D:\arduino\arduino-1.0.5\libraries\Servo/Servo.cpp:103: first defined here
 

 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Одно и тоже прерывание используют ...

maksim
Offline
Зарегистрирован: 12.02.2012
zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Большое спасибо)

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Скачал ServoTimer2 , но почему то она не цепляется и ораньжевым не подсвечивается как другие библиотеки..

Может как то не так цепляю? - скачал 2 файла ServoTimer2.cpp и ServoTimer2.h кинул в папку ServoTimer2

и кинул в libraries.

maksim
Offline
Зарегистрирован: 12.02.2012

На работоспособность это никак не влияет.

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Скачал  ServoTimer2 из другого источника всё заработало)

Покрутил сервой на расстоянии)

Пока не устраивает тормознутость и прерывистость.

Хочется понять как добавить ещё каналы чтобы не только серву крутить.

вообще буду рад примерам скетчей радиоуправления , а то есть ощущение что велосипед придумываю)

 

Такой код получился :

передатчик

#include <VirtualWire.h>
#include <EasyTransferVirtualWire.h>
#include <EEPROM.h> // эта библиотека нужна для работы с энерго-независимой памятью
#define PIN_POT 0 // Potentiometer (Analog)

int potIn=0 ;
int servo=0 ;
const int led_pin = 13;
const int transmit_pin = 2;
unsigned int unique_device_id = 0;
unsigned int count = 1;

//create object
EasyTransferVirtualWire ET; 

struct SEND_DATA_STRUCTURE{
  //наша структура данны. она должна быть определена одинаково на приёмнике и передатчике
  //кроме того, размер структуры не должен превышать 26 байт (ограничение VirtualWire)
  unsigned int device_id;
  unsigned int destination_id;    
  unsigned int packet_id;
  byte command;
  int data;
};

//переменная с данными нашей структуры
SEND_DATA_STRUCTURE mydata;

//ниже пару функций для записи данных типа unsigned int в EEPROM
void EEPROMWriteInt(int p_address, unsigned int p_value)
      {
      byte lowByte = ((p_value >> 0) & 0xFF);
      byte highByte = ((p_value >> 8) & 0xFF);

      EEPROM.write(p_address, lowByte);
      EEPROM.write(p_address + 1, highByte);
      }

unsigned int EEPROMReadInt(int p_address)
      {
      byte lowByte = EEPROM.read(p_address);
      byte highByte = EEPROM.read(p_address + 1);

      return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
      }

void setup()
{
  // блок инициализации
  pinMode(led_pin, OUTPUT);

  ET.begin(details(mydata));
  vw_set_tx_pin(transmit_pin); //установка пина, к которому подключен data-вход передатчика
  vw_setup(3000);        //скорость передачи
  Serial.begin(9600);
  randomSeed(analogRead(0));


  // Читаем/записываем Device ID
  Serial.print("Getting Device ID... "); 
  unique_device_id=EEPROMReadInt(0);
  if (unique_device_id<10000 || unique_device_id>60000) {
   Serial.print("N/A, updating... "); 
   unique_device_id=random(10000, 60000);
   EEPROMWriteInt(0, unique_device_id);
  }
  Serial.println(unique_device_id);
  
 

}

void loop()
{
  
  
  potIn = analogRead(PIN_POT); 
  servo = map(potIn, 200, 800, 890, 1900);
  
  
  mydata.device_id = unique_device_id;
  mydata.destination_id = 0;
  mydata.packet_id = random(65535);
  mydata.command = 0;
  mydata.data = servo;

  digitalWrite(led_pin, HIGH); // включаем светодиод для отображения процесса передачи
  Serial.print("Transmitting packet ");   
  Serial.print(mydata.packet_id); 
  Serial.print(" device id ");   
  Serial.print(mydata.device_id);   
  Serial.print(" data: "); 
  Serial.print(mydata.data);
  Serial.print(" ... "); 
  ET.sendData(); // отправка данных

  digitalWrite(led_pin, LOW);
  Serial.println("DONE");
  delay(10);
  
}

приемник

#include <ServoTimer2.h>
#include <VirtualWire.h>
#include <EasyTransferVirtualWire.h>
#include <EEPROM.h>
ServoTimer2 motor; 
#define PIN_MOTOR 8 // Motor ESC (Digital) 

const int led_pin = 13;
const int receive_pin = 2;
unsigned int unique_device_id = 0;

//create object
EasyTransferVirtualWire ET; 
char buf[120];

struct SEND_DATA_STRUCTURE{
  //наша структура данны. она должна быть определена одинаково на приёмнике и передатчике
  //кроме того, размер структуры не должен превышать 26 байт (ограничение VirtualWire)
  unsigned int device_id;
  unsigned int destination_id;  
  unsigned int packet_id;
  byte command;
  int data;
};

//переменная с данными нашей структуры
SEND_DATA_STRUCTURE mydata;

//ниже пару функций для записи данных типа unsigned int в EEPROM
void EEPROMWriteInt(int p_address, unsigned int p_value)
      {
      byte lowByte = ((p_value >> 0) & 0xFF);
      byte highByte = ((p_value >> 8) & 0xFF);

      EEPROM.write(p_address, lowByte);
      EEPROM.write(p_address + 1, highByte);
      }

unsigned int EEPROMReadInt(int p_address)
      {
      byte lowByte = EEPROM.read(p_address);
      byte highByte = EEPROM.read(p_address + 1);

      return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
      }

void setup()
{
    motor.attach(PIN_MOTOR);
    motor.write(0); 
    pinMode(led_pin, OUTPUT);
    Serial.begin(9600); // Debugging only

    ET.begin(details(mydata));
    // Initialise the IO and ISR
    vw_set_rx_pin(receive_pin);
    vw_setup(3000);      // Скорость приёма
    vw_rx_start();       // Запуск режима приёма
    
  // Device ID
  Serial.print("Getting Device ID... "); 
  unique_device_id=EEPROMReadInt(0);
  if (unique_device_id<10000 || unique_device_id>60000) {
   Serial.print("N/A, updating... "); 
   unique_device_id=random(10000, 60000);
   EEPROMWriteInt(0, unique_device_id);
  }
  Serial.println(unique_device_id);
  
}

void loop()
{
    if(ET.receiveData()) // получили пакет данных, обрабатываем
    {
        digitalWrite(led_pin, HIGH);
        Serial.print("Got: ");
        Serial.print("Device ID: ");
        Serial.print(mydata.device_id);
        Serial.print(" Destination ID: ");
        Serial.print(mydata.destination_id);        
        Serial.print(" Packet ID: ");
        Serial.print(mydata.packet_id);
        Serial.print(" Command: ");
        Serial.print(mydata.command);
        Serial.print(" Data: ");
        Serial.print(mydata.data);
        Serial.println();
        digitalWrite(led_pin, LOW);
        motor.write(mydata.data); 
    }
}

 

elik745i
Offline
Зарегистрирован: 08.04.2012

можете выставить ссылки с какого источника качали библиотеку, бьюсь над той же проблемой уже 3и сутки...

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Ссылки утеряны к сожалению, но библиотеку ловите)

elik745i
Offline
Зарегистрирован: 08.04.2012

короче разобрался, я вписывал #include "Arduino.h" не туда, куда надо, вот так должна выглядеть библиотека ServoTimer2.cpp:

extern "C" {
  // AVR LibC Includes
  #include <inttypes.h>
  #include <avr/interrupt.h>
  //#include "WConstants.h"
}
#include "Arduino.h"
#include <wiring.h>
#include "ServoTimer2.h"
static void initISR();   
static void writeChan(uint8_t chan, int pulsewidth);

#define FRAME_SYNC_INDEX   0		 // frame sync delay is the first entry in the channel array
#define FRAME_SYNC_PERIOD  20000	   // total frame duration in microseconds 
#define FRAME_SYNC_DELAY   ((FRAME_SYNC_PERIOD - ( NBR_CHANNELS * DEFAULT_PULSE_WIDTH))/ 128) // number of iterations of the ISR to get the desired frame rate
#define DELAY_ADJUST	 8		 // number of microseconds of calculation overhead to be subtracted from pulse timings   

static servo_t servos[NBR_CHANNELS+1];    // static array holding servo data for all channels

static volatile uint8_t Channel;   // counter holding the channel being pulsed
static volatile uint8_t ISRCount;  // iteration counter used in the interrupt routines;
uint8_t ChannelCount = 0;	    // counter holding the number of attached channels
static boolean isStarted = false;  // flag to indicate if the ISR has been initialised

ISR (TIMER2_OVF_vect)
{ 
  ++ISRCount; // increment the overlflow counter
  if (ISRCount ==  servos[Channel].counter ) // are we on the final iteration for this channel
  {
	TCNT2 =  servos[Channel].remainder;   // yes, set count for overflow after remainder ticks
  }  
  else if(ISRCount >  servos[Channel].counter)  
  {
	// we have finished timing the channel so pulse it low and move on
	if(servos[Channel].Pin.isActive == true)	     // check if activated
	    digitalWrite( servos[Channel].Pin.nbr,LOW); // pulse this channel low if active   

	  Channel++;    // increment to the next channel
	ISRCount = 0; // reset the isr iteration counter 
	TCNT2 = 0;    // reset the clock counter register
	if( (Channel != FRAME_SYNC_INDEX) && (Channel <= NBR_CHANNELS) ){	     // check if we need to pulse this channel    
	    if(servos[Channel].Pin.isActive == true)	   // check if activated
		 digitalWrite( servos[Channel].Pin.nbr,HIGH); // its an active channel so pulse it high   
	}
	else if(Channel > NBR_CHANNELS){ 
	   Channel = 0; // all done so start over		   
	} 
   }  
}

ServoTimer2::ServoTimer2()
{
   if( ChannelCount < NBR_CHANNELS)  
	this->chanIndex = ++ChannelCount;  // assign a channel number to this instance
   else
	this->chanIndex = 0;  // todo	// too many channels, assigning 0 inhibits this instance from functioning 
}

uint8_t ServoTimer2::attach(int pin)
{
	if( isStarted == false)
	 initISR();    
	if(this->chanIndex > 0)  
	{
	 //debug("attaching chan = ", chanIndex);
	 pinMode( pin, OUTPUT) ;  // set servo pin to output
	 servos[this->chanIndex].Pin.nbr = pin;  
	 servos[this->chanIndex].Pin.isActive = true;  
	} 
	return this->chanIndex ;
}

void ServoTimer2::detach()  
{
    servos[this->chanIndex].Pin.isActive = false;  
}

void ServoTimer2::write(int pulsewidth)
{	
   writeChan(this->chanIndex, pulsewidth); // call the static function to store the data for this servo	    
}

int ServoTimer2::read()
{
  unsigned int pulsewidth;
   if( this->chanIndex > 0)
	pulsewidth =  servos[this->chanIndex].counter * 128 + ((255 - servos[this->chanIndex].remainder) / 2) + DELAY_ADJUST ;
   else 
	 pulsewidth  = 0;
   return pulsewidth;   
}
 
boolean ServoTimer2::attached()
{
    return servos[this->chanIndex].Pin.isActive ;
}

static void writeChan(uint8_t chan, int pulsewidth)
{
   // calculate and store the values for the given channel
   if( (chan > 0) && (chan <= NBR_CHANNELS) )   // ensure channel is valid
   { 
	if( pulsewidth < MIN_PULSE_WIDTH )		    // ensure pulse width is valid
	    pulsewidth = MIN_PULSE_WIDTH;
	else if( pulsewidth > MAX_PULSE_WIDTH )
	    pulsewidth = MAX_PULSE_WIDTH;	 
	
	  pulsewidth -=DELAY_ADJUST;			 // subtract the time it takes to process the start and end pulses (mostly from digitalWrite) 
	servos[chan].counter = pulsewidth / 128;	
	servos[chan].remainder = 255 - (2 * (pulsewidth - ( servos[chan].counter * 128)));  // the number of 0.5us ticks for timer overflow	   
   }
}

static void initISR()
{   
	for(uint8_t i=1; i <= NBR_CHANNELS; i++) {  // channels start from 1    
	   writeChan(i, DEFAULT_PULSE_WIDTH);  // store default values	    
	}
	servos[FRAME_SYNC_INDEX].counter = FRAME_SYNC_DELAY;   // store the frame sync period	 

	Channel = 0;  // clear the channel index  
	ISRCount = 0;  // clear the value of the ISR counter;
	
	/* setup for timer 2 */
	TIMSK2 = 0;  // disable interrupts 
	TCCR2A = 0;  // normal counting mode 
	TCCR2B = _BV(CS21); // set prescaler of 8 
	TCNT2 = 0;     // clear the timer2 count 
	TIFR2 = _BV(TOV2);  // clear pending interrupts; 
	TIMSK2 =  _BV(TOIE2) ; // enable the overflow interrupt	  
	  
	isStarted = true;  // flag to indicate this initialisation code has been executed
} 

 

все заработало с некоторыми глюками, борьба продолжается...

Vermute
Offline
Зарегистрирован: 23.09.2015

Всем салют!. Тоже столкнулся с несовместимостью библиотек ServoTimer2.h и VirtualWire.h При компиляции выдает Arduino: 1.6.4 (Windows XP), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

In file included from C:\Documents and Settings\AC\Мои документы\Arduino\libraries\VirtualWire/VirtualWire.h:146:0,
                 from ExperReceiv2PWM_H_ino.ino:2:
C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:117:14: error: conflicting declaration 'typedef bool boolean'
 typedef bool boolean;
              ^
In file included from ExperReceiv2PWM_H_ino.ino:1:0:
C:\Documents and Settings\AC\Мои документы\Arduino\libraries\ServoTimer2/ServoTimer2.h:59:17: error: 'boolean' has a previous declaration as 'typedef uint8_t boolean'
 typedef uint8_t boolean;
                 ^
Ошибка компиляции.
 
В программировании не силен. В заголовочном файле Arduino.h есть обьявление типа данных(если не ошибаюсь) такого вида "typedef bool boolean".  А в хэдере библиотеки ServoTimer2.h обьявление типа "typedef uint8_t boolean". Из текста ошибки видно,что они конфликтуют. Пробовал компилировать на  старой IDE ver1.5.6. - ошибки совсем другие.  Прошу подсказать пути решения проблеммы.