Программирование Arduino+NXTI2CDEVICE
- Войдите на сайт для отправки комментариев
Вс, 03/02/2013 - 13:40
Вообщем я только начал осваиваться с arduino ,мне необходимо реализовать управление 2 сервами через serial ,serial часть у меня работает и все вроде бы хорошо но нужно подключить сервы от lego примерно так
http://robotclub.ab.ca/articles/33 ,вроде закидываю библиотеку вот сюда >> Desktop\arduino-1.0.2\libraries\тут папка NXTI2CDevice и в ней файлы cpp и .h , так как у меня версия 1,02 я во всех файлах папки во всех .h и .cpp заменил
#include "WProgram.h"
на:
#if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif
вот как то так но мне при компиляции примера пишет вот что
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp: In member function 'uint8_t* NXTI2CDevice::readRegisters(uint8_t, uint8_t, uint8_t*, uint8_t, bool)':
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp:84: error: 'class TwoWire' has no member named 'send'
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp:93: error: 'class TwoWire' has no member named 'receive'
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp: In member function 'bool NXTI2CDevice::writeRegisters(uint8_t, uint8_t, uint8_t*)':
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp:152: error: 'class TwoWire' has no member named 'send'
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp:158: error: 'class TwoWire' has no member named 'send'
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\/../Wire/utility/twi.h: In member function 'bool NXTI2CDevice::checkAddress()':
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\/../Wire/utility/twi.h:44: error: too few arguments to function 'uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t)'
E:\Users\Борис\Desktop\arduino-1.0.2\libraries\NXTI2CDevice\BaseNXTI2CDevice.cpp:235: error: at this point in file
мне как бы главное чтобы компилировались и работали эти примера а дальше я уже сам допилю их до нужного мне уровня
заранее спасибо!
PLEAAASE! HEEEELP! ME!
Замените содержимое файлов:
NXTI2CDevice.h
// NXTI2CDevice.h // // This is a class for controlling some LEGO Mindstorms NXT devices that // communicate using the I2C protocol. // // Use at your own risk! // // Initial version: 2010-05-31 by Clinton Blackmore /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef BASENXTI2CDEVICE_H #define BASENXTI2CDEVICE_H #include <Arduino.h> //#include <Wiring.c> #include <inttypes.h> inline uint16_t readIntFromBuffer(uint8_t* buf) { return buf[0] | (buf[1] << 8); } inline uint32_t readLongFromBuffer(uint8_t* buf) { return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); } inline void writeByteToBuffer(uint8_t* buf, uint8_t data) { buf[0] = data; } inline void writeByteToBuffer(uint8_t* buf, int8_t data) { writeByteToBuffer(buf, (uint8_t)data); } inline void writeIntToBuffer(uint8_t* buf, uint16_t data) { buf[0] = data & 0xFF; buf[1] = (data >> 8) & 0xFF; } inline void writeIntToBuffer(uint8_t* buf, int16_t data) { writeIntToBuffer(buf, (uint16_t)data); } inline void writeLongToBuffer(uint8_t* buf, uint32_t data) { buf[0] = data & 0xFF; buf[1] = (data >> 8) & 0xFF; buf[2] = (data >> 16) & 0xFF; buf[3] = (data >> 24) & 0xFF; } inline void writeLongToBuffer(uint8_t* buf, int32_t data) { writeLongToBuffer(buf, (uint32_t)data); } class NXTI2CDevice { // Note that this class is a base class, but not an abstract base class // Feel free to instantiate NXTI2CDevices. public: NXTI2CDevice(uint8_t i2c_address); // Routines to read registers from the I2C device // Only the first two parameters are required. uint8_t* readRegisters (uint8_t start_register, uint8_t bytes_to_read, uint8_t* buffer = 0, uint8_t buffer_length = 0, bool clear_buffer = false); uint8_t readByte (uint8_t location); uint16_t readInteger (uint8_t location); uint32_t readLong (uint8_t location); char* readString (uint8_t location, uint8_t bytes_to_read, uint8_t* buffer = 0, uint8_t buffer_length = 0); // Routines to write data to registers of the I2C device bool writeRegisters (uint8_t start_register, uint8_t bytes_to_write, uint8_t* buffer = 0); bool writeByte (uint8_t location, uint8_t data); bool writeInteger(uint8_t location, uint16_t data); bool writeLong (uint8_t location, uint32_t data); bool checkAddress(); bool setAddress(uint8_t i2c_address); uint8_t getAddress(); uint8_t getWriteErrorCode(); // Read some strings from the device. // (I believe this is consistent for all NXT I2C devices). char* getFirmwareVersion(); char* getVendorID(); char* getDeviceID(); protected: static uint8_t* _buffer; // Buffer used for data that is returned from I2C commands void setWriteErrorCode(uint8_t code); private: uint8_t _device_address; // I2C address of the NXT device uint8_t _write_error_code; // Error code from last write }; #endif // BASENXTI2CDEVICE_HNXTI2CDevice.cpp
// NXTI2CDevice.cpp // // This is a base class for NXT sensors that use the I2C protocol. // // 2010-05-31 - Initial version, by Clinton Blackmore // /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "BaseNXTI2CDevice.h" #include <Wire.h> extern "C" { #include "../Wire/utility/twi.h" } // Max I2C message length is 16 bytes. const int BUFFER_LEN = 16; // Initialize static variables uint8_t* NXTI2CDevice::_buffer = 0; NXTI2CDevice::NXTI2CDevice(uint8_t i2c_address) { // As I understand it, an I2C bus can address 127 different devices (a 7-bit quantity). // When used, the 7-bit quantity is shifted right one bit, and the last bit is clear // for a read operation and set for a write operation. Arduino's Wire library expects // a 7-bit address, but most tech specs list the 8-bit address. Hence, we drop // the least significant bit (and Wire.h shifts the address and sets the read/write // bit as appropriate.) _device_address = i2c_address >> 1; Wire.begin(); _buffer = (uint8_t*) calloc(BUFFER_LEN, sizeof(uint8_t)); } // READING FUNCTIONS // Reads registers of an I2C device. // See the documentation for your device to know what a given register // or register range indicates. uint8_t* NXTI2CDevice::readRegisters( uint8_t start_register, // start of the register range uint8_t bytes_to_read, // number of bytes to read uint8_t* buffer, // (optional) user-supplied buffer uint8_t buffer_length, // (optional) length of user-supplied buffer bool clear_buffer) // should we zero out the buffer first? (optional) { if (!buffer) { buffer = _buffer; } if (!buffer_length) { buffer_length = BUFFER_LEN; } bytes_to_read = min(bytes_to_read, buffer_length); // avoid buffer overflow if (clear_buffer) { memset(buffer, 0, buffer_length); } // We write to the I2C device to tell it where we want to read from Wire.beginTransmission(_device_address); Wire.write(start_register); //Wire.send(bytes_to_read); Wire.endTransmission(); // Now we can read the data from the device Wire.requestFrom(_device_address, bytes_to_read); for (uint8_t index = 0; Wire.available(); ++index) { buffer[index] = Wire.read(); } Wire.endTransmission(); return buffer; } // Reads a byte from the given register on the I2C device. uint8_t NXTI2CDevice::readByte(uint8_t location) { readRegisters(location, 1); return _buffer[0]; } // Reads two bytes from the given register pair on the I2C device. uint16_t NXTI2CDevice::readInteger(uint8_t location) { readRegisters(location, 2); // I believe the data has the least significant byte first return readIntFromBuffer(_buffer); } // Reads four bytes from the given registers, starting at the specified location, on the I2C device. uint32_t NXTI2CDevice::readLong(uint8_t location) { readRegisters(location, 4); return readLongFromBuffer(_buffer); } // Reads a string. Be certain that your buffer is large enough // to hold the string and a trailing 'nul'! char* NXTI2CDevice::readString( uint8_t location, // starting location of the string uint8_t bytes_to_read, // number of bytes to read uint8_t* buffer, // optional user-supplied buffer uint8_t buffer_length) // length of user-supplied buffer) { return (char *)readRegisters(location, bytes_to_read, buffer, buffer_length, true); } // WRITING FUNCTIONS // Returns true if the write was successful. // If not true, you may check the result by calling getWriteErrorCode. bool NXTI2CDevice::writeRegisters( uint8_t start_register, // start of the register range uint8_t bytes_to_write, // number of bytes to write uint8_t* buffer) // optional user-supplied buffer { if (!buffer) { buffer = _buffer; } // We write to the I2C device to tell it where we want to read from and how many bytes Wire.beginTransmission(_device_address); Wire.write(start_register); //Wire.send(bytes_to_write); // This is a guess // Send the data for (uint8_t index = 0; index < bytes_to_write; ++index) { Wire.write(buffer[index]); } _write_error_code = Wire.endTransmission(); return _write_error_code == 0; // 0 indicates success } // Writes a byte to a given register of the I2C device bool NXTI2CDevice::writeByte(uint8_t location, uint8_t data) { return writeRegisters(location, 1, &data); } // Writes two bytes to a given register of the I2C device bool NXTI2CDevice::writeInteger(uint8_t location, uint16_t data) { writeIntToBuffer(_buffer, data); return writeRegisters(location, 2, _buffer); } // Writes four bytes to a given register of the I2C device bool NXTI2CDevice::writeLong(uint8_t location, uint32_t data) { writeLongToBuffer(_buffer, data); return writeRegisters(location, 4, _buffer); } // This is the status value returned from the last write command. // A return value of zero indicates success. // Non-zero results indicate failures. From libraries/Wire/utility/twi.c, they are: // 1 .. length to long for buffer // 2 .. address send, NACK received // 3 .. data send, NACK received // 4 .. other twi error (lost bus arbitration, bus error, ..) uint8_t NXTI2CDevice::getWriteErrorCode() { return _write_error_code; } // READ SOME INFORMATION OFF OF THE DEVICE // returns a string with the current firmware version of the device char* NXTI2CDevice::getFirmwareVersion() { return readString(0, 8); } // returns a string indicating the vendor of the device char* NXTI2CDevice::getVendorID() { return readString(0x08, 8); } // returns a string indicating the device's ID char* NXTI2CDevice::getDeviceID() { return readString(0x10, 8); } // It is very unusual to do this void NXTI2CDevice::setWriteErrorCode(uint8_t code) { _write_error_code = code; } /* * checkAddress() * this function checks to see if there is * any device at a given address * - deepak */ bool NXTI2CDevice::checkAddress() { uint8_t *txBuffer; int8_t x = 1; x = twi_writeTo(_device_address, txBuffer, 0, 1, 0) == 0; return (x != 0); } /* * setAddress(address) * this function set's the i2c address * for this instance to given address * Note that, generally i2c address of a physical device does not change. * Use this function if there are multiple devices on your bus and you want to * conserve processor memory from instantiating another class instance. * - deepak */ bool NXTI2CDevice::setAddress(uint8_t i2c_address) { _device_address = i2c_address >> 1; return true; } uint8_t NXTI2CDevice::getAddress() { return _device_address; }или скачайте уже отредактированную либу.
Спасибо большое сейчас проверю , отпишусь
P.S. Так и думал что вы ответите )
побегал по темам вы почти везде даете дельные советы
да спасибо все откомпилилось
и если не секрет... где вы берете свежие библиотеки?
Максим? дело в том , что программы все компилируются ,но двигатели не крутятся и скетч который считывает данные с них на com порт отсылает это:
Vendor:
Device:
Попробуйте в NXTI2CDevice.cpp изменить строку 235
x = twi_writeTo(_device_address, txBuffer, 0, 1, 0) == 0;на
x = twi_writeTo(_device_address, txBuffer, 0, 1, 1) == 0;сейчас ок!
хммм нету .cpp есть только .h
строчку нашел в cpp файле и заменил
но ничего ничего не изменилось
Так а как у вас все подключено? Дуина какая?
Arduino UNO Atmega328P-P'J
подключено так : +5V Arduino -->> VBUS
GND Arduino -->> GRND
ANALOG IN A5 Arduino -->> SCL
ANALOG IN A4 Arduino -->> SDA
mailru агентом пользуетесь? добавьте если что я заявку кинул там по быстрее =)
если что Borolis@mail.ru
В примерах есть I2CScanner, попробуйте, найдет ли он ваши девайсы.
залил
В общем, попробуйте с другой стороны зайти. Скачайте Arduino0023 и эту библиотеку в оригинале.
происходит все в точности тоже самое
я только вот немогу понять одно, в том видео у мужичка подключено 2 таких сервы и на одном моменте написано как подключено http://youtu.be/ixUF2UhLpk8?t=34s всетаки там же 2 сервы и какн он их тогда подключил? обе посадил на одни и те же контакты?
если есть возможность зайдите в агент?
происходит все в точности тоже самое
я только вот немогу понять одно, в том видео у мужичка подключено 2 таких сервы и на одном моменте написано как подключено http://youtu.be/ixUF2UhLpk8?t=34s всетаки там же 2 сервы и какн он их тогда подключил? обе посадил на одни и те же контакты?
хорошо сейчас все подключу обратно
я вот незнаю что делать , завтра пойду поменяю сервы на другие,может с этими что не так?
Вот еще какой момент был упущен - на линиях SDA и SCL должны стоять подтягивающие резисторы к +5V по 4,7кОм.
если к +5V то как я понимаю можно активировать Внутреннй подтягивающий резистор.
В микроконтроллерах ATmega168 и ATmega328 есть внутренние подтяжки. Они имеют номинал 20Ком и включаются программно. Нужно иметь в виду что внутренняя подтяжка "Прижимает" пин только к +5в ?
Или это возможно только для цифровых пинов?
Сейчас притянул SDA и SCL к +5в но все по прежнему
Сопротивление подтяжки около 60кОм, что примерно в 12 раз больше нужного, попробуйте поставить резисторы на 4,7кОм и посмотреть через I2CScanner.
Подтянул резисторами 4,67 кОм и ничего не изменилось
Еще раз перепроверьте правильность подключения и прозвоните линии, выложите фото.
И попробуйте вот этот сканер:
// -------------------------------------- // i2c_scanner // // This program (or code that looks like it) // can be found in many places. // For example on the Arduino.cc forum. // The original author is not know. // // This sketch tests the standard 7-bit addresses // from 0 to 127. Devices with higher bit address // might not be seen properly. // // Adapted to be as simple as possible by Arduino.cc user Krodal // // June 2012 // Using Arduino 1.0.1 // #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 0; address <= 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(8000); // wait 8 seconds for next scan }Вопрос до сих пор не решен, с заведомо рабочими серво-двигателями тоже не работает,проблема либо в коде либо в подключении