конфликт библиотек VirtualWire.h и Servo.h
- Войдите на сайт для отправки комментариев
Сб, 10/08/2013 - 17:05
Собственно хотелось попробовать поковырятся с радио управлением на таких простейших модулях 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
Servo\Servo.cpp.o:D:\arduino\arduino-1.0.5\libraries\Servo/Servo.cpp:103: first defined here
Одно и тоже прерывание используют ...
http://electronics.stackexchange.com/questions/67967/problems-using-servo-h-and-virtualwire-h-in-arduino
https://code.google.com/p/arduino-ppm-servo/source/browse/libraries/ServoTimer2/?r=aab59dc77be59ab9ea3c119c922ff94359b6b24c#ServoTimer2%253Fstate%253Dclosed
Большое спасибо)
Скачал ServoTimer2 , но почему то она не цепляется и ораньжевым не подсвечивается как другие библиотеки..
Может как то не так цепляю? - скачал 2 файла ServoTimer2.cpp и ServoTimer2.h кинул в папку ServoTimer2
и кинул в libraries.
На работоспособность это никак не влияет.
Скачал 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); } }можете выставить ссылки с какого источника качали библиотеку, бьюсь над той же проблемой уже 3и сутки...
Ссылки утеряны к сожалению, но библиотеку ловите)
короче разобрался, я вписывал #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 }все заработало с некоторыми глюками, борьба продолжается...
Всем салют!. Тоже столкнулся с несовместимостью библиотек ServoTimer2.h и VirtualWire.h При компиляции выдает Arduino: 1.6.4 (Windows XP), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"