I am using teensy with rosserial + ROS Noetic/Ubuntu 20.04 on RASPI4. The teensy code is implemented with ros_lib on platformio (https://platformio.org/lib/show/5526/...). The program compiles fine and uploads successfully on port /dev/ttyACM0. However, when I do rosrun rossserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=500000 then I get the sync failed error.
[ERROR] [1612795964.166906]: Unable to sync with device; possible link
problem or link software version mismatch such as hydro
rosserial_python with groovy Arduino.
Things I have already tried:
a) Setting correct baudrate in Serial.begin(500000)
b) Disabling all Serial.begin and Serial.print statements
c) Setting baudrate of ros node nh.gethardware()->setbaud(500000) before nh.init()
d) Increasing the default buffer size to 1024 in ros.h of ros_lib
typedef NodeHandle_<arduinohardware, 10,="" 10,="" 1024,="" 1024=""> NodeHandle;
e) Tried the Arduino board instead of Teensy and the problem still remain.
However, nothing has worked so far.
The default baud rate for rosserial is 56700. For changing it you will need to do the following
Modify the include statement in the arduino code from
#include <ros.h>
to
#include "ros.h"
Add the following header files alongside the .ino/.pde file
ros.h
#ifndef _ROS_H_
#define _ROS_H_
#include "ros/node_handle.h"
#include "ArduinoHardware.h"
namespace ros
{
typedef NodeHandle_<ArduinoHardware> NodeHandle;
}
#endif
ArduinoHardware.h
#ifndef ROS_ARDUINO_HARDWARE_H_
#define ROS_ARDUINO_HARDWARE_H_
#if ARDUINO>=100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <HardwareSerial.h>
#define SERIAL_CLASS HardwareSerial
class ArduinoHardware
{
public:
ArduinoHardware()
{
iostream = &Serial;
baud_ = 500000;
}
void setBaud(long baud)
{
this->baud_= baud;
}
int getBaud()
{
return baud_;
}
void init()
{
iostream->begin(baud_);
}
int read()
{
return iostream->read();
};
void write(uint8_t* data, int length)
{
for(int i=0; i<length; i++)
{
iostream->write(data[i]);
}
}
unsigned long time()
{
return millis();
}
protected:
SERIAL_CLASS* iostream;
long baud_;
};
#endif
In the ArduinoHeader.h file we defined above the iostream & the baud rate to be used is set using the constructor as shown below
ArduinoHardware()
{
iostream = &Serial;
baud_ = 500000;
}
as you are using teensy with USB the iostream will be Serial. If you are using the pins and not the USB it will vary from Serial1 to Serial8 as mentioned here. The baud rate of the teensy can be varied by varying the baud_ here set to 500000.
This code is referenced from Advanced Configuration for NodeHandle and ArduinoHardware
Related
I'm trying to send out data from SPI, but can't get it to work. There appear no data on the SPI ports (D12, 13, 14; checked with an oscilloscope) and the ESP32 seems to hang. I would like to use the HSPI port.
I am also wondering whether I need a special driver for SPI to work on ESP32 and if so, how can I check if I already have that and how do I install it. When I look in the library manager, I see no special SPI driver.
I have tried using this program (copied from https://diyi0t.com/spi-tutorial-for-arduino-and-esp8266/). It's apparently intended for esp8266. Should it work out of the box also for ESP32?
#include "SPI.h"
char buff[]="Hello Slave\n";
void setup() {
SPI.begin();
}
void loop() {
for(int i=0; i<sizeof buff; i++)
{
SPI.transfer(buff[i]);
}
delay(1000);
}
and also with this program:
#include "SPI.h"
char buff[]="Hello Slave\n";
SPIClass SPI1(HSPI);
void setup() {
SPI1.begin();
SPI1.setClockDivider(80);
}
void loop() {
for(int i=0; i<sizeof buff; i++)
{
SPI1.transfer(buff[i]);
}
delay(1000);
}
I am using a 30 pin ESP32 dev board, Arduino version 1.8.13. In preferences-->more board managers, it says:
http://arduino.esp8266.com/stable/package_esp8266com_index.json, https://dl.espressif.com/dl/package_esp32_index.json
For ESP32, you need to declare which SPI instance you want to use, like so:
#include <SPI.h>
SPIClass SPI1(HSPI);
SPI1.begin();
// Optional
// SPI1.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE2));
The rest is the same as ESP8266
#include <SPI.h>
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_CS 15
static const int spiClk = 240000000; // 1 MHz
SPIClass * hspi = NULL;
char buff[]="Hello Slave\n";
//byte buff[] = {0xAA, 0xBB, 0xAA, 0x01,
0x89, 0xAB, 0xCD, 0xEF};
void setup() {
Serial.begin(9600);
hspi = new SPIClass(HSPI);
hspi->begin();
hspi->begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_CS); //SCLK, MISO, MOSI, SS
pinMode(HSPI_CS, OUTPUT); //HSPI SS
}
void loop() {
for(int i=0; i<sizeof buff; i++)
{
SPI.transfer(buff[i]);
Serial.println(buff[i]);
}
delay(1000);
}
Assuming that you use the ESP32 Arduino Core, under the docs it is written that SPI is has a suppported Arduino API implementation. Thus using the Arduino SPI API, it should work, like all other devices (the ESP32 Arduino Core implementation conforms to the API defined by Arduino, of course I would check if your board's pinout corresponds to the Espressif defined ESP32 pinout).
If you want to see some examples, you can find one here. All supported APIs have examples on the ESP32 Arduino Core repo on GitHub.
I also want to point out that in the Arduino IDE (or the VSCode plugin) you can find examples for SPI, I would take a look as well for that.
I am working on a project that involves a BLE scanner using ESP32. I use the installed BLE scanner sample code in Arduino IDE to program the ESP32 but the device is unable to scan for the names of iBeacon just like any normal android BLE scanner application. I also tried to modify the code to specifically extract the names of iBeacons only but I still end up with the same result. Any suggestions are welcomed. Here is my modified code:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
//Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
Serial.print("Name :");
Serial.println(advertisedDevice.getName().c_str());
}
};
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop() {
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000);
}
I am able to transfer data from one arduino to another using nRF24L01 chips. However, I need the data to be sent ONLY when a specific command is sent on the serial port. I want to be able to write 'A' on the serial port, and for arduino to reply with the latest data. This is easy with the serialcommand library and works if I am directly plugged in. However, the moment I add the nRF24L01 module, serialcommand.h does not respond with the data anymore. I tried even removing the if (radio.available()) .. so no data would be received and just the fact that there is radio.begin() in setup makes the serialcommand 'A' not work. when I remove the radio stuff, the command 'A' does reply with three zeros (default data).
Here is my receiver code. I still consider myself a beginner and i never formally studied C/C++. Any help or ideas as to why this happens is very appreciated!
.
#include <SoftwareSerial.h>
#include <SerialCommand.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
SerialCommand sCmd;
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
int Array[3];
void setup() {
Serial.begin(9600);
sCmd.addCommand("A", serialdataPrint );
radio.begin();
radio.setRetries(15, 15);
radio.openReadingPipe(0,address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
while (Serial.available() > 0){
sCmd.readSerial();
if (radio.available()) {
int Array_received[3];
radio.read(&Array_received, sizeof(Array_received));
Array[0] = Array_received[0];
Array[1] = Array_received[1];
Array[2] = Array_received[2];
}
}
}
void serialdataPrint ()
{
Serial.println(Array[0]);
Serial.println(Array[1]);
Serial.println(Array[2]);
}
I can use the MFRC522 using the following code:
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
void setup() {
SPI.begin();
mfrc522.PCD_Init();
}
void loop() {
if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
// Do stuff
}
}
And it works great. I can also use the dot-matrix (8x8) using the following code:
#include "LedControl.h"
LedControl lc = LedControl(12,11,8,1);
void setup() {
lc.shutdown(0,false);
lc.setIntensity(0,3);
lc.clearDisplay(0);
lc.setLed(0,2,5,true);
lc.setLed(0,5,5,true);
lc.setLed(0,2,2,true);
lc.setLed(0,3,1,true);
lc.setLed(0,4,1,true);
lc.setLed(0,5,2,true);
}
void loop() {
}
And it works just fine as well. However, when I try to use both of them using the following code:
#include <SPI.h>
#include <MFRC522.h>
#include "LedControl.h"
LedControl lc = LedControl(12,11,8,1);
MFRC522 mfrc522(10, 9);
void setup() {
SPI.begin();
mfrc522.PCD_Init();
lc.shutdown(0,false);
lc.setIntensity(0,3);
lc.clearDisplay(0);
lc.setLed(0,2,5,true);
lc.setLed(0,5,5,true);
lc.setLed(0,2,2,true);
lc.setLed(0,3,1,true);
lc.setLed(0,4,1,true);
lc.setLed(0,5,2,true);
}
void loop() {
if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
// Do stuff
}
}
In that case only one of them works (the MFRC522). I know that since they are connected in SPI mode they need to have different SS pins, so I used pin 10 for MFRC522 and pin 8 for dot-matrix. So, what's wrong? Why dot-matrix doesn't work at the same code with MFRC522??
Without the datasheets at hand, I'd first suspect that the two SPI devices have clock rates that are incompatible. You need to find the clock rates for each one and either clock them off two different timers, or switch timing on a single timer to provide the correct clock rate for the currently selected device. Incompatible clock rates has been the only problem I've ever had with SPI devices.
I have some problem with my own arduino library. Compiler does not recognize my class Platform and says: "error: 'Platform' does not name a type".
Here is the main program code:
#include <Platform.h>
#define MOVE_FORWARD 0xFF
#define MOVE_BACKWARD 0xF0
// Error 'Platform' does not name a type
Platform plt(13, 14, 15);
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.read() == MOVE_FORWARD)
plt.move(5);
if (Serial.read() == MOVE_BACKWARD)
plt.move(-5);
}
Here is the Platform.h code:
#ifndef PLATFORM_H
#define PLATFORM_H
#include <arduino.h>
#include <Motor.h>
class Platform {
public:
Platform(int input_1, int input_2, int enable); // Pins for L293D
void move(int distance);
private:
Motor *m_motors; // All motors connected to one L293D
};
#endif
And implementation of Platform:
#include "Platform.h"
Platform::Platform(int input_1, int input_2, int enable){
m_motors = new Motor(input_1, input_2, enable);
}
void Platform::move(int distance){
byte mm_delay = 100;
byte motor_power = 128;
if (distance > 0)
m_motors->forvard(motor_power);
else if (distance < 0)
m_motors->backward(motor_power);
delay(mm_delay*distance);
m_motors->stop();
}
The behavior of the compiler is pretty strange for me because the Motor library work nice and structure of Platform.h is the same as structure of Motor.h.
From above program it is clear that error report your getting because of below reason . you need to change header include file from #include <Platform.h> to include "Platform.h".