class CSpeakJet
{
public:
CSpeakJet(uint8_t receive_pin, uint8_t transmit_pin, uint8_t is_speaking_pin);
void Begin();
void SetVolume(int lVol);
void SetPitch(int lPitch);
void SetSpeed(int lSpeed);
void SetBend(int lBend);
void Play(uint8_t* data, int len, bool wait);
void Play(int id, bool wait);
void PlayNumber(int number, bool wait);
void AddByte(uint8_t data);
void Wait();
private:
SoftwareSerial mSerial;
uint8_t mSpeakingPin;
};
This class provides functions to set volume/pitch/speed/bend, and a 2 ways to play a sound. The first simply sends a series of bytes to the speech jet. However the second takes an index into a hard coded list of sounds:
enum ESpeech
{
SPEECH_HELLO,
SPEECH_YOUR,
SPEECH_ENGINE,
SPEECH_IS,
SPEECH_BOUNCY,
SPEECH_I,
SPEECH_CAN,
SPEECH_SEE,
SPEECH_YOU,
SPEECH_DEGREES,
SPEECH_ANGLE,
SPEECH_DISTANCE,
SPEECH_0,
SPEECH_1,
SPEECH_2,
SPEECH_3,
SPEECH_4,
SPEECH_5,
SPEECH_6,
SPEECH_7,
SPEECH_8,
SPEECH_9,
TOTAL_SPEECH
};
In amongst these are the numbers 0 to 9. All that needs to happen now is a simple function to extract the digits of a number and say them, rather like converting numbers to strings. After a bit of fiddling I come up with this, which could be better but does the job for now:
void CSpeakJet::PlayNumber(int number)
{
int orignumber = number;
if(orignumber >= 1000)
Play(int(SPEECH_0+number/1000));
number = number % 1000;
if(orignumber >= 100)
Play(int(SPEECH_0+number/100));
number = number % 100;
if(orignumber >= 10)
Play(int(SPEECH_0+number/10));
number = number % 10;
Play(int(SPEECH_0+number/1));
}
Next up it's time to connect the CMP03 electronic compass. I introduced this device in the Bob The Boe Bot post earlier. However it wasn't massively useful, as it communicated using pulse width modulation which was too slow. This time we'll be hooking it up via an I2C Bus, as shown below.
Compass with I2C connection |
Developed by Philips, this clever system is a common way for multiple devices to communicate with a microcontroller, normally in master/slave configuration. The master can choose to send a message to one of the devices on the network and sends it's address down the data line, followed by the data. It then waits while the slave sends a response. It's too much to explain right now but there's lots of info here. If you're starting to robot you'll need this soon.
Compass connected to I2C via Analog pins |
The Arduino has built in support for I2C and can act as master or slave. On the Uno this is done using Analog Pins 4 and 5, along with a library to send and receive data through it.
Arduino devices, now with CMP03 Compass |
Here you see the circuit from the last blog which includes PING, Motion and Speak Jet, now with an added Compass connected via I2C to Analog In 4+5 on the Arduino. Using the Wire library we can then communicate with the compass using a hardcoded address that the sensor stores.
//read value from 0 to 359 degrees
#define ADDRESS 0x60 //defines address of compass
int readCompass(){
byte highByte;
byte lowByte;
Wire.beginTransmission(ADDRESS); //starts communication with cmps03
Wire.write(2); //Sends the register we wish to read
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 2); //requests high byte
while(Wire.available() < 2); //wait for 2 bytes
highByte = Wire.read(); //reads the bytes as a integers
lowByte = Wire.read();
return ((highByte<<8)+lowByte)/10; //combine and return 16 bit integer
}
With a bit of work, I plug all the bits together to get:
- Wait until button clicked
- Read compass and ping sensor
- Say 'Compass'
- Using PlayNumber function I wrote earlier to say the compass reading
- Say 'Distance'
- Use PlayNumber again to say the distance reading
And here's a little video of it in action (if vid doesn't work, check on you tube here):
And there you have it - the Arduino using a SpeakJet to read out measurements from a compass and ultra sound sensor when
No comments:
Post a Comment