I'm trying to use the BNO055 magnetometer/gyroscope/accelerometer with an ATTINY85.
I cannot for the life of me get the simplest BNO055 example sketch to compile with SoftwareSerial, every change I make to try and get it to work seems to return a littany of errors, the one that seems to recur the most is "mySerial not declared in this scope".
My question is, will the BNO055 even work with the ATTINY85? Or am I barking up a wrong tree?
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 4
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
/* This driver reads raw data from the BNO055
Connections
===========
Connect SCL to analog 5
Connect SDA to analog 4
Connect VDD to 3.3V DC
Connect GROUND to common ground
History
=======
2015/MAR/03 - First release (KTOWN)
*/
/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (100)
Adafruit_BNO055 bno = Adafruit_BNO055();
/**************************************************************************/
/*
Arduino setup function (automatically called at startup)
*/
/**************************************************************************/
void setup(void)
{
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
mySerial.begin(9600);
mySerial.println("Orientation Sensor Raw Data Test"); mySerial.println("");
/* Initialise the sensor */
if(!bno.begin())
{
/* There was a problem detecting the BNO055 ... check your connections */
mySerial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
while(1);
}
delay(1000);
/* Display the current temperature */
int8_t temp = bno.getTemp();
mySerial.print("Current Temperature: ");
mySerial.print(temp);
mySerial.println(" C");
mySerial.println("");
bno.setExtCrystalUse(true);
mySerial.println("Calibration status values: 0=uncalibrated, 3=fully calibrated");
}
/**************************************************************************/
/*
Arduino loop function, called once 'setup' is complete (your own code
should go here)
*/
/**************************************************************************/
void loop(void)
{
// Possible vector values can be:
// - VECTOR_ACCELEROMETER - m/s^2
// - VECTOR_MAGNETOMETER - uT
// - VECTOR_GYROSCOPE - rad/s
// - VECTOR_EULER - degrees
// - VECTOR_LINEARACCEL - m/s^2
// - VECTOR_GRAVITY - m/s^2
imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
/* Display the floating point data */
mySerial.print("X: ");
mySerial.print(euler.x());
mySerial.print(" Y: ");
mySerial.print(euler.y());
mySerial.print(" Z: ");
mySerial.print(euler.z());
mySerial.print("\t\t");
/*
// Quaternion data
imu::Quaternion quat = bno.getQuat();
Serial.print("qW: ");
Serial.print(quat.w(), 4);
Serial.print(" qX: ");
Serial.print(quat.y(), 4);
Serial.print(" qY: ");
Serial.print(quat.x(), 4);
Serial.print(" qZ: ");
Serial.print(quat.z(), 4);
Serial.print("\t\t");
*/
/* Display calibration status for each sensor. */
uint8_t system, gyro, accel, mag = 0;
bno.getCalibration(&system, &gyro, &accel, &mag);
mySerial.print("CALIBRATION: Sys=");
mySerial.print(system, DEC);
mySerial.print(" Gyro=");
mySerial.print(gyro, DEC);
mySerial.print(" Accel=");
mySerial.print(accel, DEC);
mySerial.print(" Mag=");
mySerial.println(mag, DEC);
delay(BNO055_SAMPLERATE_DELAY_MS);
}
The "Wire" library doesn't work with a 'tiny85, (no hardware I2C, only a Universal Serial Interface). You'll need an alternative library, perhaps "TinyWireM".
Regarding "SoftwareSerial", this compiles fine for me with a 'tiny85 as the target:-
'A' received
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Hi there from 'tiny85
Y'all might be interested in using NeoSWSerial instead of SoftwareSerial, if the baud rate is 9600, 19200 or 38400. It doesn't block interrupts for the entire time a character is being received. And unlike SoftwareSerial, NeoSWSerial can transmit and receive at the same time.
There is software to use the USI as a serial port here. That would be much better than any software serial library, but it can only use pins 0 and 1.
/dev:
There is software to use the USI as a serial port here. That would be much better than any software serial library, but it can only use pins 0 and 1.
Cheers,
/dev
That's clearly why PaulS thought "SoftwareSerial" could only use pins 0 and 1.
Looks a bit trickier to use though.
Generally, I use I2C for communication with tiny84 and tiny85 chips, since distances are usually short in my creations.
Still handy to be aware of what's available, though. I just downloaded the "NeoSWSerial" lib, and will give it a spin when I get a chance.
Hi guys, just wanted to express my gratitude for helping me figure this all out and show my solutions to any future searchers.
Oldsteve, your suggestions got the SoftwareSerial working for me, seems I just had to tweak a few things to be closer to your suggestions.
TinyWireM was not working for me at first, but upon finding that I had an old version of Adafruit_BNO055.h, I downloaded the more recent from github and was up and running right away!
Here is a simplified version of the code I came up with that will return euler angles over Softwareserial.
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <SoftwareSerial.h>
const byte rxPin = 3; // Physical pin 2
const byte txPin = 4; // Physical pin 3
SoftwareSerial mySerial (rxPin, txPin);
/* This driver reads raw data from the BNO055
Connections
===========
Connect SCL to analog 5
Connect SDA to analog 4
Connect VDD to 3.3V DC
Connect GROUND to common ground
History
=======
2015/MAR/03 - First release (KTOWN)
*/
Adafruit_BNO055 bno = Adafruit_BNO055();
void setup(void)
{
mySerial.begin(9600);
/* Initialise the sensor */
if(!bno.begin())
delay(1000);
bno.setExtCrystalUse(true);
}
void loop(void)
{
imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
/* Display the floating point data */
mySerial.print(" X: ");
mySerial.print(euler.x());
mySerial.print(" Y: ");
mySerial.print(euler.y());
mySerial.print(" Z: ");
mySerial.print(euler.z());
mySerial.println("\t\t");
delay(100);
}
You know what, I wasn't really sure what that was, but when I tried to remove it, the sketch quit working. There was some code after that that serial prints "BNO055 not connected" or something to that effect. I removed it since there's such limited memory on the ATTINY85.
I assumed it was necessary, what precisely is that there to do?
zakelectric:
You know what, I wasn't really sure what that was, but when I tried to remove it, the sketch quit working. There was some code after that that serial prints "BNO055 not connected" or something to that effect. I removed it since there's such limited memory on the ATTINY85.
I assumed it was necessary, what precisely is that there to do?
'bno.begin()' is absolutely necessary, to initialise the sensor. What I was querying was the fact that the code still continues on to use the sensor even if 'begin()' fails.
I think you changed the intent of the code when you removed the print line etc.
I'd be more likely to write something like:-
if (!bno.begin())
{
mySerial.print(F("Failed to initialise the BNO055 sensor - cannot continue!"));
while(true); // Loop forever, (stop code execution).
}
so that you're informed of the problem if the sensor can't be initialised, then code execution stops.