Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:d493a3003022, committed 2013-05-21
- Comitter:
- jose_claudiojr
- Date:
- Tue May 21 13:51:07 2013 +0000
- Commit message:
- Example of reading an accelerometer sensor (BMA180)
Changed in this revision
diff -r 000000000000 -r d493a3003022 Accelerometer.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Accelerometer.cpp Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,100 @@
+
+#include "Accelerometer.h"
+
+Accelerometer::Accelerometer(BMA180* acceleHardware, float sensitivity)
+{
+ this->acceleHardware = acceleHardware;
+ this->sensitivity = sensitivity;
+ updateZeroRates();
+}
+
+Accelerometer::~Accelerometer(void)
+{
+}
+
+void Accelerometer::updateZeroRates()
+{
+ update(253, 10); // Utilizando filtro passa baixa, é necessário 253 amostras para estabilização do filtro.
+ update(200, 10);
+ zeroRateX = rawX;
+ zeroRateY = rawY;
+ zeroRateZ = rawZ;
+ //zeroRateX = 0.0;
+ //zeroRateY = 0.0;
+ //zeroRateZ = 0.0;
+}
+
+void Accelerometer::update()
+{
+ update(1, 1);
+}
+
+void Accelerometer::update(int samplesSize, int sampleDataRate)
+{
+ int axes[3] = {0, 0, 0};
+ rawX = 0;
+ rawY = 0;
+ rawZ = 0;
+
+ for (int i = 0; i < samplesSize; i++)
+ {
+
+ rawX += (this->acceleHardware->getX() / samplesSize);
+ rawY += (this->acceleHardware->getY() / samplesSize);
+ rawZ += (this->acceleHardware->getZ() / samplesSize);
+
+ //this->acceleHardware->getOutput(axes);
+
+ //rawX += ((float)axes[0] / samplesSize);
+ //rawY += ((float)axes[1] / samplesSize);
+ //rawZ += ((float)axes[2] / samplesSize);
+ wait_ms(sampleDataRate);
+ }
+}
+
+float Accelerometer::getAccelerationX()
+{
+ //( * Vref / 1023 – VzeroG) / Sensitivity
+ return ((rawX - zeroRateX) / sensitivity); //Devido a posição da plaquinha, quando se define o zeroRateX, tem que adicionar novamente a gravidade, que está influenciando o X
+}
+
+float Accelerometer::getAccelerationY()
+{
+ return ((rawY - zeroRateY) / sensitivity);
+}
+
+float Accelerometer::getAccelerationZ()
+{
+ return (((rawZ - zeroRateZ) / sensitivity) + 1.0);
+}
+
+float Accelerometer::getRadiansAngleX()
+{
+ float x = getAccelerationX();
+ float z = getAccelerationZ();
+
+ return (float)atan2(x, z);
+}
+
+float Accelerometer::getRadiansAngleY()
+{
+ float x = getAccelerationX();
+ float y = getAccelerationY();
+ float z = getAccelerationZ();
+ return (float)atan2(y, z);
+}
+
+float Accelerometer::getDegreesAngleX()
+{
+ return (getRadiansAngleX() / Accelerometer::getPI()) * 180.0;
+}
+
+float Accelerometer::getDegreesAngleY()
+{
+ return (getRadiansAngleY() / Accelerometer::getPI()) * 180.0;
+}
+
+float Accelerometer::getPI()
+{
+ return 3.14159265;
+}
diff -r 000000000000 -r d493a3003022 Accelerometer.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Accelerometer.h Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,42 @@
+#ifndef ACCELEROMETER_H
+#define ACCELEROMETER_H
+
+#include <math.h>
+
+#include "BMA180.h"
+
+class Accelerometer
+{
+ public:
+ Accelerometer(BMA180* acceleHardware, float sensitivity);
+ ~Accelerometer(void);
+
+ void updateZeroRates();
+
+ void update();
+ void update(int samplesSize, int sampleDataRate);
+
+ float getAccelerationX();
+ float getAccelerationY();
+ float getAccelerationZ();
+
+ float getRadiansAngleX();
+ float getRadiansAngleY();
+
+ float getDegreesAngleX();
+ float getDegreesAngleY();
+
+ static float getPI();
+
+ private:
+ BMA180* acceleHardware;
+
+ float sensitivity;
+ float zeroRateX, zeroRateY, zeroRateZ;
+
+ float rawX;
+ float rawY;
+ float rawZ;
+};
+
+#endif
diff -r 000000000000 -r d493a3003022 BMA180.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BMA180.cpp Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,173 @@
+#include "mbed.h"
+#include "BMA180.h"
+/* Range em default value: 2g (010) / Resolução do ADC 0.25mg/LSB sensibilidade 4096 (LSBadc/g)
+ * Range Register: 0x35
+ * Valor Range Resolução ADC (mg/LSB) =================================
+ * 000 1g 0.13 || Prestar atenção nas unidades||
+ * 001 1.5g 0.19 =================================
+ * 010 2g 0.25
+ * 011 3g 0.38
+ * 100 4g 0.50
+ * 101 8g 0.99
+ * 110 16g 1.98
+ */
+BMA180::BMA180(PinName sda, PinName scl): i2c(sda, scl)
+{
+ char rx, temp1, temp2;
+ i2c.frequency(100000);
+ //Testar depois com 400KHz
+ //==========================================================================================================
+ // Read chip_id
+ //==========================================================================================================
+ rx = Read(BMA180_WHO_AM_I);
+ if (rx != BMA180_ID)//ID do chip
+ printf("\ninvalid chip id %d\r\n", rx);
+ //==========================================================================================================
+ // Set CTRLREG0 0x0D, bit ee_w (0001 0000) to update image and make it possible write in to the chip eeprom
+ //==========================================================================================================
+ rx = Read(BM180_CTRLREG0);
+ rx |= 0x10;
+ Write(BM180_CTRLREG0, rx);
+ //Let's confirm
+ rx = Read(BM180_CTRLREG0);
+ temp1 = rx | 0x10;
+ if(rx != temp1)
+ printf("\nee_w bit wasn't changed %d\r\n", rx);
+ // ee_w bit set, OK
+ //==========================================================================================================
+ // Let's define the low-pass filter's bandwidth to 10Hz (bw<3:0> -> 0000), to reduce noise in the signal
+ // To set the bw bit, we will have to acces the bw_tcs register (0x20)
+ //==========================================================================================================
+ rx = Read(BM180_BWTCS);
+ // procedure: readed value: i.e 0101 0101
+ temp1 = 0x00; // (AND) 0000 1111 -> (~BWMask)
+ temp1 = temp1 << 4; // ---------
+ rx &= (~0xF0); //Mask // (OR) 0000 0101
+ rx |= temp1; // Wanted Value <-[0000]0000 -> Wanted value with 4's complement
+ Write(BM180_BWTCS, rx); // ---------
+ //Let's confirm // 0000 0101 -> Final Value
+ rx = Read(BM180_BWTCS);
+ temp2 = rx;
+ temp1 = 0x00;
+ temp1 = temp1 << 4;
+ temp2 &= (~0xF0); //Mask
+ temp2 |= temp1;
+ if(rx != temp2)
+ printf("\nbw bit wasn't changed %d\r\n", rx);
+ // low-pass filter's bandwidth defined, OK
+
+ //==========================================================================================================
+ // Let's set the range to 2g (0x02) in the
+ //==========================================================================================================
+ rx = Read(BMA180_OLSB1); // procedure: value to set with 1's complement 0000 [010]0
+ temp1 = 0x02; // readed value: i.e 0101 0101
+ temp1 = temp1 << 1; // (AND) 1111 0001 -> RangeMask
+ rx &= (~0x0E); // ---------
+ rx |= temp1; // 0101 0001
+ Write(BMA180_OLSB1, rx); // (OR) 0000 0100 -> Shifted value
+ // Let's confirm // ---------
+ rx = Read(BMA180_OLSB1); // 0101 0101 -> Final Value
+ temp2 = rx;
+ temp1 = 0x02;
+ temp1 = temp1 << 1;
+ temp2 &= (~0x0E);
+ temp2 |= temp1;
+ if(rx != temp2)
+ printf("\nRange not set %d\r\n", rx);
+}
+
+void BMA180::Write(char reg, char data)
+{
+ char c_data[2];
+ c_data[0] = reg;
+ c_data[1] = data;
+ i2c.write(BMA180_ADDR, c_data, 2);
+}
+
+char BMA180::Read(char data)
+{
+ char tx = data;
+ char rx;
+
+ i2c.write((BMA180_ADDR) & 0xFE, &tx, 1); // 0xFE ensure that the MSB bit is being set to zero (RW=0 -> Writing)
+ i2c.read((BMA180_ADDR) | 0x01, &rx, 1); // 0x01 ensure that the MSB bit is being set to one (RW=1 -> Reading)
+ // The read/write method of I2C does this automatically, so it's useless to set manually
+ return rx;
+}
+
+void BMA180::MultiByteRead(char address, char* output, int size)
+{
+ i2c.write( (BMA180_ADDR) & 0xFE, &address, 1); //tell it where to read from
+ i2c.read( (BMA180_ADDR) | 0x01 , output, size); //tell it where to store the data read
+}
+
+float BMA180::getX()
+{
+ char lsb_byte = 0;
+ signed short msb_byte;
+ float acc;
+
+ while (lsb_byte != 1)
+ {
+ lsb_byte = Read(BMA180_XLSB) & 0x01;
+ }
+
+ lsb_byte = Read(BMA180_XMSB);
+ msb_byte = lsb_byte << 8;
+ msb_byte |= Read(BMA180_XLSB);
+ msb_byte = msb_byte >> 2; // Get rid of two non-value bits in LSB
+ //printf("%d \t", msb_byte);
+ acc = (float)msb_byte;
+ return acc;
+}
+
+float BMA180::getY()
+{
+ char lsb_byte = 0;
+ signed short msb_byte;
+ float acc;
+
+ while (lsb_byte != 1)
+ {
+ lsb_byte = Read(BMA180_YLSB) & 0x01;
+ }
+
+ lsb_byte = Read(BMA180_YMSB);
+ msb_byte = lsb_byte << 8;
+ msb_byte |= Read(BMA180_YLSB);
+ msb_byte = msb_byte >> 2; // Get rid of two non-value bits in LSB
+ //printf("%d \t", msb_byte);
+ acc = (float)msb_byte;
+ return acc;
+}
+
+float BMA180::getZ()
+{
+ char lsb_byte = 0;
+ signed short msb_byte;
+ float acc;
+
+ while (lsb_byte != 1)
+ {
+ lsb_byte = Read(BMA180_ZLSB) & 0x01;
+ }
+
+ lsb_byte = Read(BMA180_ZMSB);
+ msb_byte = lsb_byte << 8;
+ msb_byte |= Read(BMA180_ZLSB);
+ msb_byte = msb_byte >> 2; // Get rid of two non-value bits in LSB
+ //printf("%d \t", msb_byte);
+ acc = (float)msb_byte;
+ return acc;
+}
+
+void BMA180::getOutput(int* readings)
+{
+ char buffer[6];
+ MultiByteRead(BMA180_XLSB, buffer, 6);
+
+ readings[0] = (int)buffer[1] << 8 | (int)buffer[0];
+ readings[1] = (int)buffer[3] << 8 | (int)buffer[2];
+ readings[2] = (int)buffer[5] << 8 | (int)buffer[4];
+
+}
\ No newline at end of file
diff -r 000000000000 -r d493a3003022 BMA180.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BMA180.h Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,38 @@
+#ifndef MBED_BMA180_H
+#define MBED_BMA180_H
+
+#define BMA180_WHO_AM_I 0x00
+#define BMA180_ID 0x03
+#define BMA180_ADDR 0x80 //datasheet says 0x40 !
+#define BMA180_XLSB 0x02 //LSB
+#define BMA180_XMSB 0x03 //MSB
+
+#define BMA180_YLSB 0x04 //LSB
+#define BMA180_YMSB 0x05 //MSB
+
+#define BMA180_ZLSB 0x06 //LSB
+#define BMA180_ZMSB 0x07 //MSB
+
+#define BM180_CTRLREG0 0x0D
+#define BM180_BWTCS 0x20
+#define BMA180_OLSB1 0x35
+
+#include "mbed.h"
+
+class BMA180 {
+public:
+ BMA180(PinName sda, PinName scl);
+
+ float getX();
+ float getY();
+ float getZ();
+ void getOutput(int* readings);
+private:
+ void Write(char reg, char data);
+ char Read(char);
+ void MultiByteRead(char address, char* output, int size);
+ I2C i2c;
+ int16_t x,y,z;
+};
+
+#endif
diff -r 000000000000 -r d493a3003022 SerialBuffered.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.cpp Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,180 @@
+#include "SerialBuffered.h"
+
+/**
+ * Create a buffered serial class.
+ *
+ * @param tx A pin for transmit.
+ * @param rx A pin for receive.
+ */
+SerialBuffered::SerialBuffered(PinName tx, PinName rx) : Serial(tx, rx)
+{
+ indexContentStart = 0;
+ indexContentEnd = 0;
+ timeout = 1;
+
+ attach(this, &SerialBuffered::handleInterrupt);
+}
+
+/**
+ * Destroy.
+ */
+SerialBuffered::~SerialBuffered()
+{
+}
+
+/**
+ * Set timeout for getc().
+ *
+ * @param ms milliseconds. (-1:Disable timeout)
+ */
+void SerialBuffered::setTimeout(int ms)
+{
+ timeout = ms;
+}
+
+/**
+ * Read requested bytes.
+ *
+ * @param bytes A pointer to a buffer.
+ * @param requested Length.
+ *
+ * @return Readed byte length.
+ */
+size_t SerialBuffered::readBytes(uint8_t *bytes, size_t requested)
+{
+ int i = 0;
+
+ while (i < requested)
+ {
+ int c = getc();
+
+ if (c < 0)
+ {
+ break;
+ }
+
+ bytes[i] = c;
+ i++;
+ }
+
+ return i;
+}
+
+/**
+ * Get a character.
+ *
+ * @return A character. (-1:timeout)
+ */
+int SerialBuffered::getc()
+{
+ timer.reset();
+ timer.start();
+
+ while (indexContentStart == indexContentEnd)
+ {
+ wait_ms(1);
+
+ if ((timeout > 0) && (timer.read_ms() > timeout))
+ {
+ /*
+ * Timeout occured.
+ */
+ // printf("Timeout occured.\n");
+ return EOF;
+ }
+ }
+
+ timer.stop();
+
+ uint8_t result = buffer[indexContentStart++];
+ indexContentStart = indexContentStart % BUFFERSIZE;
+
+ return result;
+}
+
+/**
+ * Returns 1 if there is a character available to read, otherwise.
+ */
+int SerialBuffered::readable()
+{
+ return indexContentStart != indexContentEnd;
+}
+
+void SerialBuffered::handleInterrupt()
+{
+ while (Serial::readable())
+ {
+ if (indexContentStart == ((indexContentEnd + 1) % BUFFERSIZE))
+ {
+ /*
+ * Buffer overrun occured.
+ */
+ // printf("Buffer overrun occured.\n");
+ Serial::getc();
+ }
+ else
+ {
+ buffer[indexContentEnd++] = Serial::getc();
+ indexContentEnd = indexContentEnd % BUFFERSIZE;
+ }
+ }
+}
+
+float SerialBuffered::f_readIntTo(char delimiter)
+{
+ char buffer[16];
+ int i;
+ float result;
+ for (i = 0;; i++)
+ {
+ //while (!readable());
+
+ char number = getc();
+
+ if (number == delimiter)
+ break;
+
+ buffer[i] = number;
+ }
+
+ buffer[i-1] = '\0';
+
+ result = atof(buffer);
+
+ return result;
+}
+
+
+int SerialBuffered::i_readIntTo(char delimiter)
+{
+ char buffer[16];
+ int i;
+ float result;
+ for (i = 0;; i++)
+ {
+ //while (!readable());
+
+ char number = getc();
+
+ if (number == delimiter)
+ break;
+
+ buffer[i] = number;
+ }
+
+ buffer[i-1] = '\0';
+
+ result = atoi(buffer);
+
+ return result;
+}
+
+void SerialBuffered::writeText(char* text)
+{
+ for (int i = 0; text[i] != '\0' && i < BUFFER_TEXT_SIZE; i++)
+ {
+ while (!Serial::writeable());
+
+ Serial::putc(text[i]);
+ }
+}
diff -r 000000000000 -r d493a3003022 SerialBuffered.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.h Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,71 @@
+#ifndef _SERIAL_BUFFERED_H_
+#define _SERIAL_BUFFERED_H_
+
+#include "mbed.h"
+
+/**
+ * Buffered serial class.
+ */
+class SerialBuffered : public Serial
+{
+ public:
+ /**
+ * Create a buffered serial class.
+ *
+ * @param tx A pin for transmit.
+ * @param rx A pin for receive.
+ */
+ SerialBuffered(PinName tx, PinName rx);
+
+ /**
+ * Destroy.
+ */
+ virtual ~SerialBuffered();
+
+ /**
+ * Get a character.
+ *
+ * @return A character. (-1:timeout)
+ */
+ int getc();
+
+ /**
+ * Returns 1 if there is a character available to read, otherwise.
+ */
+ int readable();
+
+ /**
+ * Set timeout for getc().
+ *
+ * @param ms milliseconds. (-1:Disable timeout)
+ */
+ void setTimeout(int ms);
+
+ /**
+ * Read requested bytes.
+ *
+ * @param bytes A pointer to a buffer.
+ * @param requested Length.
+ *
+ * @return Readed byte length.
+ */
+ size_t readBytes(uint8_t *bytes, size_t requested);
+
+ float f_readIntTo(char delimiter);
+ int i_readIntTo(char delimiter);
+ void writeText(char* text);
+
+ private:
+ void handleInterrupt();
+
+ static const int BUFFERSIZE = 2048;
+ static const int BUFFER_TEXT_SIZE = 255;
+
+ uint8_t buffer[BUFFERSIZE]; // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
+ uint16_t indexContentStart; // index of first bytes of content
+ uint16_t indexContentEnd; // index of bytes after last byte of content
+ int timeout;
+ Timer timer;
+};
+
+#endif
diff -r 000000000000 -r d493a3003022 main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue May 21 13:51:07 2013 +0000
@@ -0,0 +1,43 @@
+#include "mbed.h"
+#include "BMA180.h"
+#include "Accelerometer.h"
+
+#define SDA p9
+#define SCL p10
+Serial pc(USBTX, USBRX);
+//Serial pc(p28, p27);
+int main()
+{
+ float x,y,z, AngleX, AngleY;
+ pc.printf("Inicializing...\r\n");
+ BMA180 *bma180 = new BMA180(SDA, SCL);
+ Accelerometer acc(bma180, 4096);
+
+ pc.printf("OK...\r\n");
+ wait(1);
+ //max G
+
+ //y = bma180->getY();
+ //z = bma180->getZ();
+
+ //printf("%f\n%f\n%f", x,y,z);
+
+
+ //acc->updateZeroRates();
+
+ while(1)
+ {
+ acc.update();
+ x = acc.getAccelerationX();
+ y = acc.getAccelerationY();
+ z = acc.getAccelerationZ();
+
+ AngleX = acc.getDegreesAngleX();
+ AngleY = acc.getDegreesAngleY();
+
+ pc.printf("x: %.2f \t\ty: %.2f \t\tz: %.2f \t\tAngleX: %.2f \t\tAngleY: %.2f \t\r\n", x, y, z, AngleX, AngleY);
+ //x = bma180->getX();
+ //printf("%f\r\n", x);
+ wait_ms(200);
+ }
+}
diff -r 000000000000 -r d493a3003022 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue May 21 13:51:07 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/10b9abbe79a6 \ No newline at end of file