Embedded system Fun Blog
























































Find out all the best information, libraries and circuit about the latest Embedded systems.
Showing posts with label sensor. Show all posts
Showing posts with label sensor. Show all posts

Sunday, 6 January 2013

Arduino code for MAX6675

.from: https://github.com/codebendercc/arduino-files/blob/master/extra-libraries/max6675/max6675.cpp

X================================X max6675.h X================================X

// this library is public domain. enjoy!
// www.ladyada.net/learn/sensors/thermocouple

#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

class MAX6675 {
 public:
  MAX6675(int8_t SCLK, int8_t CS, int8_t MISO);

  double readCelsius(void);
  double readFahrenheit(void);
  // For compatibility with older versions:
  double readFarenheit(void) { return readFahrenheit(); }
 private:
  int8_t sclk, miso, cs;
  uint8_t spiread(void);
};

X================================X max6675.cpp X================================X

// this library is public domain. enjoy!
// www.ladyada.net/learn/sensors/thermocouple

#include <avr pgmspace.h="pgmspace.h">
#include <util delay.h="delay.h">
#include <stdlib .h=".h">
#include "max6675.h"

MAX6675::MAX6675(int8_t SCLK, int8_t CS, int8_t MISO) {
  sclk = SCLK;
  cs = CS;
  miso = MISO;

  //define pin modes
  pinMode(cs, OUTPUT);
  pinMode(sclk, OUTPUT);
  pinMode(miso, INPUT);

  digitalWrite(cs, HIGH);
}
double MAX6675::readCelsius(void) {

  uint16_t v;

  digitalWrite(cs, LOW);
  _delay_ms(1);

  v = spiread();
  v &lt;&lt;= 8;
  v |= spiread();

  digitalWrite(cs, HIGH);

  if (v &amp; 0x4) {
    // uh oh, no thermocouple attached!
    return NAN;
    //return -100;
  }

  v &gt;&gt;= 3;

  return v*0.25;
}

double MAX6675::readFahrenheit(void) {
  return readCelsius() * 9.0/5.0 + 32;
}

byte MAX6675::spiread(void) {
  int i;
  byte d = 0;

  for (i=7; i&gt;=0; i--)
  {
    digitalWrite(sclk, LOW);
    _delay_ms(1);
    if (digitalRead(miso)) {
      //set the bit to 0 no matter what
      d |= (1 &lt;&lt; i);
    }

    digitalWrite(sclk, HIGH);
    _delay_ms(1);
  }

  return d;
}

X================================X X================================X


</stdlib></util></avr>

Exemple code I2C bmp085 pressure sensor

.from: https://github.com/codebendercc/arduino-files/blob/master/extra-libraries/ArduSat-I2Csensors/bmp085.cpp


X=========================X bmp085.h X=========================X


/*
bmp085.h
libary for using the I2C bmp085 pressure sensor

(c) Written by Jeroen Cappaert for NanoSatisfi, August 2012
*/


#ifndef bmp085_h
#define bmp085_h

#include <Arduino.h>

#define BAR_ADDR 0x77 // Barometric pressure sensor I2C address


class bmp085
{
 public:
   //constructor
    bmp085();
    //functions
    void configBaro();
    int bmp085ReadInt(int device, byte address);
    unsigned int baroReadUT();
    unsigned long baroReadUP();
    float getTempFromBaro(unsigned int ut);
    long getPressFromBaro(unsigned long up);
    void getBmpData(float bmp[]);
    //variables
    int ac1;
    int ac2;
    int ac3;
    unsigned int ac4;
    unsigned int ac5;
    unsigned int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;
    int barOSS;
    long b5;
  private:
};


#endif


X=========================X bmp085.cpp X=========================X

/*
bmp085.cpp
libary for using the I2C bmp085 pressure sensor

(c) Written by Jeroen Cappaert for NanoSatisfi, August 2012
*/

#include <Arduino.h>
#include "bmp085.h"
#include <Wire.h>


//Constructor
bmp085::bmp085()
{
  barOSS = 2;
}

//configure barometer
void bmp085::configBaro()
{
  ac1 = bmp085ReadInt(BAR_ADDR, 0xAA);
  ac2 = bmp085ReadInt(BAR_ADDR, 0xAC);
  ac3 = bmp085ReadInt(BAR_ADDR, 0xAE);
  ac4 = bmp085ReadInt(BAR_ADDR, 0xB0);
  ac5 = bmp085ReadInt(BAR_ADDR, 0xB2);
  ac6 = bmp085ReadInt(BAR_ADDR, 0xB4);
  b1 = bmp085ReadInt(BAR_ADDR, 0xB6);
  b2 = bmp085ReadInt(BAR_ADDR, 0xB8);
  mb = bmp085ReadInt(BAR_ADDR, 0xBA);
  mc = bmp085ReadInt(BAR_ADDR, 0xBC);
  md = bmp085ReadInt(BAR_ADDR, 0xBE);
}

// user function: get pressure and temperature from sensor with one command
void bmp085::getBmpData(float bmp[])
{
 bmp[0] = getTempFromBaro(baroReadUT());
 bmp[1] = getPressFromBaro(baroReadUP());
}


// calculate temperature given ut
float bmp085::getTempFromBaro(unsigned int ut)
{
  long x1, x2;
  
  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;

  return (float) ((b5 + 8)>>4)/10.;
}


// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085::getPressFromBaro(unsigned long up)
{
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;
  
  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<barOSS) + 2)>>2;
  
  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  
  b7 = ((unsigned long)(up - b3) * (50000>>barOSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;
    
  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;
  
  return p;
}


// read uncorrected temperature value from bmp085
unsigned int bmp085::baroReadUT()
{
  unsigned int ut;
  
  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BAR_ADDR);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();
  
  // Wait at least 4.5ms
  delay(5);
  
  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(BAR_ADDR,0xF6);
  return ut;
}


// read uncorrected pressure value from bmp085
unsigned long bmp085::baroReadUP()
{
  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;
  
  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BAR_ADDR);
  Wire.write(0xF4);
  Wire.write(0x34 + (barOSS<<6));
  Wire.endTransmission();
  
  // Wait for conversion, delay time dependent on OSS
  delay(2 + (3<<barOSS));
  
  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  Wire.beginTransmission(BAR_ADDR);
  Wire.write(0xF6);
  Wire.endTransmission();
  Wire.requestFrom(BAR_ADDR,3);
  
  // Wait for data to become available
  while(Wire.available() < 3)
    ;
  msb = Wire.read();
  lsb = Wire.read();
  xlsb = Wire.read();
  
  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-barOSS);
  
  return up;
}



// read integer on bmp085
int bmp085::bmp085ReadInt(int device, byte address)
{
  unsigned char msb, lsb;
  
  Wire.beginTransmission(device);
  Wire.write(address);
  Wire.endTransmission();
  
  Wire.requestFrom(device, 2);
  while(Wire.available()<2)
    ;
  msb = Wire.read();
  lsb = Wire.read();
  
  return (int) msb<<8 | lsb;
}



X=========================X X=========================X

Monday, 5 March 2012

How to Use MBED as a mouse to Play AngryBirdz

How to Use MBED as a mouse

.from: http://mbed.org/cookbook/Slingshot


Check this in action!

USB Slingshot
So now you can kill pigs with a real USB Slingshot, by combining the two totally different worlds of carpentry and embedded systems!

XXXXXXXXXXXXXXXXXXXXXXXX main.cpp XXXXXXXXXXXXXXXXXXXXXXXXXXX


/* mbed USB Slingshot, 
 *
 * Copyright (c) 2010-2011 mbed.org, MIT License
 * 
 * smokrani, sford
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 *  The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "mbed.h"
#include "USBMouse.h"
#include "ADXL345.h"

// Physical interfaces
USBMouse mouse;
ADXL345 accelerometer(p5, p6, p7, p8);
AnalogIn stretch_sensor(p15);
BusOut leds(LED1, LED2, LED3, LED4);

// Return slingshot angle in radians, up > 0 > down
float get_angle() {
    int readings[3];
    accelerometer.getOutput(readings);
    float x = (int16_t)readings[0];
    float z = (int16_t)readings[2];
    return atan(z / x);    
}

// Return normalised stretch value based on bounds of all readings seen
float get_stretch() {
    static float min_strength = 0.7;
    static float max_strength = 0.7;
    float current_strength = stretch_sensor.read();
    if(current_strength > max_strength) { max_strength = current_strength; }
    if(current_strength < min_strength) { min_strength = current_strength; }
    float stretch = (current_strength - min_strength) / (max_strength - min_strength);
    return 1.0 - stretch;
}

// move mouse to a location relative to the start point, stepping as needed
void move_mouse(int x, int y) {
    const int STEP = 10;
    static int current_x = 0;
    static int current_y = 0;
    
    int move_x = x - current_x;
    int move_y = y - current_y; 

    // Move the mouse, in steps of max step size to ensure it is picked up by OS
    while(move_x > STEP) { mouse.move(STEP, 0); move_x -= STEP; }
    while(move_x < -STEP) { mouse.move(-STEP, 0); move_x += STEP; }
    while(move_y > STEP) { mouse.move(0, STEP); move_y -= STEP; }
    while(move_y < -STEP) { mouse.move(0, -STEP); move_y += STEP; }
    mouse.move(move_x, move_y);
    
    current_x = x;
    current_y = y;
}

template <class T>
T filter(T* array, int len, T value) {
    T mean = 0.0;
    for(int i = 0; i<len - 1; i++) {
        mean += array[i + 1];
        array[i] = array[i + 1];
    }
    mean += value;
    array[len - 1] = value;
    return mean / (T)len;
}

typedef enum {
    WAITING = 2,
    AIMING = 4,
    FIRING = 8
} state_t;

int main() {
    leds = 1;

    // setup accelerometer
    accelerometer.setPowerControl(0x00);
    accelerometer.setDataFormatControl(0x0B);
    accelerometer.setDataRate(ADXL345_3200HZ);
    accelerometer.setPowerControl(0x08);

    state_t state = WAITING;    
    Timer timer;

    float angles[8] = {0};
    float stretches[8] = {0};
    
    while(1) {        

        // get the slingshot parameters
        float this_stretch = get_stretch();
        float this_angle = get_angle();

        // apply some filtering
        float stretch = filter(stretches, 8, this_stretch);
        float angle = filter(angles, 8, this_angle);
            
        leds = state;
                
        // act based on the current state
        switch (state) {
            case WAITING:
                if(stretch > 0.5) {             // significant stretch, considered starting 
                    mouse.press(MOUSE_LEFT);
                    state = AIMING;
                }
                break;

            case AIMING:
                if(stretch - this_stretch > 0.1) { // rapid de-stretch, considered a fire
                    mouse.release(MOUSE_LEFT);
                    move_mouse(0, 0);
                    timer.start();
                    state = FIRING;
                } else {
                    int x = 0.0 - cos(angle) * stretch * 200;
                    int y = sin(angle) * stretch * 200;
                    move_mouse(x, y);
                }
                break;

            case FIRING:
                if(timer > 3.0) {
                    timer.stop();
                    timer.reset();
                    state = WAITING;
                }        
                break;
        };
        
        wait(0.01);
    }
}

XXXXXXXXXXXXXXXXXXXXXXXX test.cpp XXXXXXXXXXXXXXXXXXXXXXXXXXX

#include "mbed.h"
#include "USBMouse.h"
#include "ADXL345.h"
 
USBMouse mouse;
ADXL345 acc(p5, p6, p7, p8);
AnalogIn strength(p15);
 
int main() {
    //Initialize accelerometer
    acc.setPowerControl(0x00);
    acc.setDataFormatControl(0x0B);
    acc.setDataRate(ADXL345_3200HZ);
    acc.setPowerControl(0x08);
 
    while (1) {
        int readings[3];
        acc.getOutput(readings);        // test accelerometer
        printf("acc: %i, %i, %i\r\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
 
        uint16_t str = strength.read_u16();        // test stretch sensor
        printf("strength: %d\r\n", str);
       
        mouse.move(10, 10);             // test USB relative mouse

        wait(0.1);
    }
}
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
 
 

Here is the pinout table:
ADXL345 Signal Namembed pin
VccVout
GndGnd
SDAp5
SDOp6
SCLp7
CSp8
Stretch sensormbed pin
One extremityVout
The otherp15
USB connectormbed pin
VccVin
GndGnd
D+D+
D-D-


Sunday, 8 January 2012

MBED: Read BH1751FVI Digital Light Sensor IC using I2C (CookBook)

.from: mbed.org/users/hasegawa00/notebook/digital-light-sensor-ic-bh1751fvi/

.datasheet: http://www.rohm.com/products/databook/sensor/pdf/bh1751fvi-e.pdf

/media/uploads/hasegawa00/_scaled_201111031116000.jpg


XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx main.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

#include "mbed.h"

I2C i2c(p9, p10);        // sda, scl
Serial pc(USBTX, USBRX); // tx, rx
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);

const int addr = 0x46; // define the I2C Address L
int mode = 1, mode0;
float echo, bai = 1.0;
int main() {
    char cmd[2];
    char cmdr[2];

    cmd[0] = 0x01;           // Power On
    i2c.write(addr, cmd, 1);
    cmd[0] = 0x07;           // Reset
    i2c.write(addr, cmd, 1);
    cmd[0] = 0x42;           // Typ Upper-bit
    i2c.write(addr, cmd, 1);
    cmd[0] = 0x65;           // Typ Lower-bit
    i2c.write(addr, cmd, 1);
    cmd[0] = 0x10;           // H-resolutiom Mode
    i2c.write(addr, cmd, 1);

    myled1 = 1;
    while(1) {
        myled2 = 1;
        wait(0.18);              // 
        if(mode == 0) wait(0.54);
        i2c.read(addr, cmdr, 2); // read the 2-byte echo result
        echo = ((cmdr[0] << 8) + cmdr[1]) / 1.2 * bai;

        mode0 = mode;
        if(mode == 0){
            if(echo >= 6000){
                mode = 2;
            }else if(echo >= 1000){
                mode = 1;
            }
        }
        if(mode == 1){
            if(echo < 100){
                mode = 0;
            }
            if(echo >= 30000){
                mode = 2;
            }
        }
        if(mode == 2){
            if(echo < 60){
                mode = 0;
            }else if(echo < 3000){
                mode = 1;
            }
        }
        if(mode != mode0){
            if(mode == 0){
                cmd[0] = 0x47;           // Max Upper-bit
                i2c.write(addr, cmd, 1);
                cmd[0] = 0x7E;           // Max Lower-bit
                i2c.write(addr, cmd, 1);
                cmd[0] = 0x11;           // H-resolutiom Mode2
                i2c.write(addr, cmd, 1);
                bai = (69.0 / 254.0) / 2.0;
            }
            if(mode == 1){
                cmd[0] = 0x42;           // Typ Upper-bit
                i2c.write(addr, cmd, 1);
                cmd[0] = 0x65;           // Typ Lower-bit
                i2c.write(addr, cmd, 1);
                cmd[0] = 0x10;           // H-resolutiom Mode
                i2c.write(addr, cmd, 1);
                bai = 1.0;
            }
            if(mode == 2){
                cmd[0] = 0x40;           // Min Upper-bit
                i2c.write(addr, cmd, 1);
                cmd[0] = 0x7F;           // Min Lower-bit
                i2c.write(addr, cmd, 1);
                cmd[0] = 0x10;           // H-resolutiom Mode
                i2c.write(addr, cmd, 1);
                bai = 69.0 / 31.0;
            }
            wait(2.0);              // 
            i2c.read(addr, cmdr, 2); // read the 2-byte echo result
            echo = ((cmdr[0] << 8) + cmdr[1]) / 1.2 * bai;
        }

        pc.printf("light = %.2f mode = %d bai = %.2f\r\n", echo, mode, bai);
        myled2 = 0;
        wait(0.82);
    }

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

MBED: Read TMP102 Temperature Sensor using I2C (Cookbook)

.from: http://mbed.org/users/donatien/programs/TMP102/5z9h3

The TMP102 is another I2C digital temperature sensor in a small SOT563 package
/media/uploads/chris/tmp102_crop.jpg
TMP102mbed
1 - Vcc (square pad)Vout
2 - SDAp9
3 - SCLp10
4 - GndGnd

XxXxXxXxXxXxXxXxXxXxXxXxXxXx TMP102.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx


/*
Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "TMP102.h"

#define TEMP_REG_ADDR 0x00

TMP102::TMP102(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr)
{

}

TMP102::~TMP102()
{

}

float TMP102::read()
{
  I2C temperatureIn(p9, p10);
 
  const char tempRegAddr = TEMP_REG_ADDR;

  m_i2c.write(m_addr, &tempRegAddr, 1); //Pointer to the temperature register

  char reg[2] = {0,0};
  m_i2c.read(m_addr, reg, 2); //Rea
 
  unsigned short res = (reg[0] << 4) | (reg[1] >> 4);
 
  float temp =  (float) ((float)res * 0.0625);
  
  return temp;
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx TMP102.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx


/*
Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef TMP102_H
#define TMP102_H

#include "mbed.h"

//!Library for the TI TMP102 temperature sensor.
/*!
The TMP102 is an I2C digital temperature sensor in a small SOT563 package, with a 0.0625C resolution and 0.5C accuracy.
*/
class TMP102
{
public:
  //!Creates an instance of the class.
  /*!
  Connect module at I2C address addr using I2C port pins sda and scl.
  TMP102
  \param addr <table><tr><th>A0 pin connection</th><th>Address</th></tr><tr><td>GND</td><td>0x90</td></tr><tr><td>V+</td><td>0x92</td></tr><tr><td>SDA</td><td>0x94</td></tr><tr><td>SCL</td><td>0x96</td></tr></table> 
  */
  TMP102(PinName sda, PinName scl, int addr);
 
  /*!
  Destroys instance.
  */
  ~TMP102();
 
  //!Reads the current temperature.
  /*!
  Reads the temperature register of the TMP102 and converts it to a useable value.
  */
  float read();
 
private:
  I2C m_i2c;
  int m_addr;

};

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXx





MBED SPI Sensor: How to read AD7904 output

.from: http://mbed.org/forum/mbed/topic/2444/

#include "mbed.h"

DigitalOut cs(p10);
SPI spi(p5, p6, p7);
Serial pc(USBTX, USBRX);

int adc;

int main()
{
    pc.baud(115200);
    pc.format(8,Serial::None,1);

    spi.format(16,3);
    spi.frequency(1000000);

   
    // dump read
    pc.printf("dump read\r\n");
    cs = 0;
    adc = spi.write(0x8300);
    cs = 1;
    pc.printf("ADC = %d\r\n", adc);

    // real reading
    pc.printf("real reading\r\n");
    cs = 0;
    adc = spi.write(0x0000);
    cs = 1;
    pc.printf("ADC = %d\r\n", adc);
}


MBED SPI Sensor: How to read AD7914 output

.from: http://mbed.org/forum/mbed/topic/2444/

#include "mbed.h"

DigitalOut cs(p10);
SPI spi(p5, p6, p7);
Serial pc(USBTX, USBRX);

int adc;

int main()
{
    pc.baud(115200);
    pc.format(8,Serial::None,1);

    spi.format(16,3);
    spi.frequency(1000000);

   
    // dump read
    pc.printf("dump read\r\n");
    cs = 0;
    adc = spi.write(0x8300);
    cs = 1;
    pc.printf("ADC = %d\r\n", adc);

    // real reading
    pc.printf("real reading\r\n");
    cs = 0;
    adc = spi.write(0x0000);
    cs = 1;
    pc.printf("ADC = %d\r\n", adc);
}


MBED SPI Sensor: How to read AD7924 output

.from: http://mbed.org/forum/mbed/topic/2444/

#include "mbed.h"

DigitalOut cs(p10);
SPI spi(p5, p6, p7);
Serial pc(USBTX, USBRX);

int adc;

int main()
{
    pc.baud(115200);
    pc.format(8,Serial::None,1);

    spi.format(16,3);
    spi.frequency(1000000);

   
    // dump read
    pc.printf("dump read\r\n");
    cs = 0;
    adc = spi.write(0x8300);
    cs = 1;
    pc.printf("ADC = %d\r\n", adc);

    // real reading
    pc.printf("real reading\r\n");
    cs = 0;
    adc = spi.write(0x0000);
    cs = 1;
    pc.printf("ADC = %d\r\n", adc);
}


MBED Snipet: Reading the WHOAMI register of an LIS302 accelerometer using SPI

.from: http://mbed.org/handbook/SPI?action=view&revision=442

#include "mbed.h"

SPI spi(p5, p6, p7); // mosi, miso, sclk
DigitalOut cs(p8);

Serial pc(USBTX, USBRX); // tx, rx

int main() {
    // Setup the spi for 8 bit data, high steady state clock,
    // second edge capture, with a 1MHz clock rate
    spi.format(8,3);
    spi.frequency(1000000);

    // Select the device by seting chip select low
    cs = 0;

    // Send 0x8f, the command to read the WHOAMI register
    spi.write(0x8F);

    // Send a dummy byte to receive the contents of the WHOAMI register
    int whoami = spi.write(0x00);
    pc.printf("WHOAMI register = 0x%X\n", whoami);

    // Deselect the device
    cs = 1;
}
 
/media/uploads/mbedofficial/spi_interfaces.png 

Saturday, 7 January 2012

MBED Example: How to use MB1210 Max Botix ultrasonic range finder model 1210 libraries

.from: http://mbed.org/users/Blaze513/programs/MB1210/5zqck


XxXxXxXxXxXxXxXxXxXxXxXxXxXx MB1210.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//mbed Microcontroller Library
//Max Botix Ultrasonic Range Finder MB1210 Interface
//Copyright 2010
//Thomas Hamilton

#include "MB1210.h"

MB1210::MB1210(PinName pw, PinName an, PinName tx, PinName rx) : OperatingMode(0x00),
    UnitFactor(1), PwmScalingFactor(17014.5), AnalogScalingFactor(1024), Range(0)
{
    if (rx != NC)
    {
        SerialInput = new Serial(NC, rx);
        SerialInput->baud(9600);
        SerialInput->format(8, Serial::None, 1);
        SerialInput->attach(NULL, Serial::RxIrq);
        OperatingMode = 0x02;
    }
    if (an != NC)
    {
        AnalogInput = new AnalogIn(an);
        OperatingMode = 0x01;
    }
    if (pw != NC)
    {
        PwmInput = new PwmIn(pw);
        OperatingMode = 0x00;
    }
    if (tx != NC)
    {
        SerialOutput = new DigitalOut(tx);
        SerialOutput->write(0);
    }
}
    //constructor dynamically allocates memory and cpu time (interrupts)
    //to input objects depending on how the device is connected

MB1210::~MB1210()
{
    delete PwmInput;
    delete AnalogInput;
    delete SerialOutput;
    delete SerialInput;
    delete this;
}
    //input objects must be deallocated

void MB1210::SoundVelocity(float MetersPerSecond)
{
    PwmScalingFactor = (UnitFactor * MetersPerSecond * 50);
}
    //set the velocity of sound for pwm readings

void MB1210::Voltage(float Volts)
{
    AnalogScalingFactor = (UnitFactor * 3379.2 / Volts);
}
    //set the voltage correction factor for analog readings

void MB1210::Unit(float UnitsPerMeter)
{
    PwmScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
    AnalogScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
    UnitFactor = UnitsPerMeter / 100;
}
    //set the unit factor to return the range in units other than cm

void MB1210::Mode(char Selection)
{
    if (SerialInput)
    {
        if (Selection & 0x08)
        {
            SerialInput->attach(this, &MB1210::Interrupt, Serial::RxIrq);
        }
        else
        {
            SerialInput->attach(NULL, Serial::RxIrq);
        }
            //attach or detach the interrupt function
    }
        //interrupts can only be generated if rx pin is connected
    if (SerialOutput)
    {
        SerialOutput->write(Selection & 0x04);
    }
        //synchronous modes can only be set if tx pin is connected
    OperatingMode = Selection & 0x03;
}
    //change the operating mode; SerialOutput controls synchronicity

void MB1210::AttachInterruptBuffer(float* Buffer)
{
    InterruptBuffer = Buffer;
}
    //the user changes the pointer to their own storage area so they can use the interrupt

void MB1210::RequestSyncRead()
{
    if (SerialOutput)
    {
        SerialOutput->write(1);
        wait_us(20);
        SerialOutput->write(0);
    }
}
    //hold pin high for at least 20 us to request a synchronous range reading

void MB1210::DiscardSerialBuffer()
{
    while (SerialInput->readable())
    {
        SerialInput->getc();
    }
}
    //read characters from the buffer until it is empty

float MB1210::Read()
{
    switch (OperatingMode)
    {
        case 0:
            if (PwmInput)
            {
                return PwmInput->pulsewidth() * PwmScalingFactor;
            }
            else
            {
                return 0;
            }
        case 1:
            if (AnalogInput)
            {
                return AnalogInput->read() * AnalogScalingFactor;
            }
            else
            {
                return 0;
            }
        case 2:
            if (SerialInput)
            {
                unsigned char i = 0;
                while (SerialInput->readable() && !SerialInput->scanf("R%3f", &Range) && (i < 32))
                {
                    SerialInput->getc();
                    i++;
                }
                    //find R and parse the range out
                return Range * UnitFactor;
            }
            else
            {
                return 0;
            }
        default:
            return 0;
    }
}
    //OperatingMode switches to desired output method;
    //the result is scaled according to voltage, the speed of sound, and desired unit

void MB1210::Interrupt()
{
    *InterruptBuffer = Read();
    DiscardSerialBuffer();
}
    //this is called whenever an interrupt mode is
    //set and a serial rx interrupt is generated;
    //it writes to the user's data storage area

MB1210::operator float()
{
    return Read();
}
    //conversion function acts as shorthand for Read()

XxXxXxXxXxXxXxXxXxXxXxXxXxXx MB1210.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//mbed Microcontroller Library
//Max Botix Ultrasonic Range Finder MB1210 Interface
//Copyright 2010
//Thomas Hamilton

#ifndef MB1210Library
#define MB1210Library

#include "mbed.h"
#include "PwmIn.h"

class MB1210
{
    private:
        PwmIn* PwmInput;
        AnalogIn* AnalogInput;
        DigitalOut* SerialOutput;
        Serial* SerialInput;

        char OperatingMode;
        float UnitFactor;
        float PwmScalingFactor;
        float AnalogScalingFactor;
        float Range;
        float* InterruptBuffer;

        void Interrupt();

    public:
        MB1210(PinName pw, PinName an, PinName tx, PinName rx);
            //pulse width modulation input, analog input, serial output, serial input;
            //specify NC if pin is not used;
            //if the pulse width pin is used, interrupts will perform a
            //few microseconds of calculations every time a reading is taken
        ~MB1210();
            //deallocates PwmInput, AnalogInput, SerialOutput, and SerailInput
        void SoundVelocity(float MetersPerSecond);
            //if, for some reason, you need to correct the speed of sound
            //for Pwm modes, enter the new value here in meters per second;
            //default is 340.29 m/s
            //Note: most accurate mode
        void Voltage(float Volts);
            //sets expected operating voltage for Analog modes;
            //user responsibility to ensure operating voltage between 3.3 V and 5 V;
            //default is 3.3 V
        void Unit(float UnitsPerMeter);
            //argument sets the putput units through multiplication;
            //default is cm
        void Mode(char Selection);
            //argument sets operating mode;
            //set flag 0x08 to 0 for polled modes, or 1 for interrupt modes;
            //set flag 0x04 to 0 for synchronous modes, or 1 for asynchronous modes;
            //set flags 0x03 to 0 for pwm, 1 for analog, or 2 for serial;
            //asynchronous modes generate pulse width interrupts, prepare an
            //analog reading, and send a 5 byte serial reading every 99 ms;
            //interrupt modes automatically read the range into the buffer provided
            //by AttachInterruptBuffer with the selected input method every 99 ms
            //if in an asynchronous mode, or 99 ms after RequestSyncRead is called;
            //the rx pin must be connected to use an interrupt mode;
            //the tx pin must be connected to use a synchronous mode;
            //default is 0
        void AttachInterruptBuffer(float* Buffer);
            //if interrupts are used, user must provide address to write result to
        void RequestSyncRead();
            //this tells the device to prepare a synchronous range reading;
            //must be called at least 99 ms before the reading is needed;
            //changes asynchronous mode to synchronous equivalent
        void DiscardSerialBuffer();
            //the serial port has a buffer and only the oldest data is read from it;
            //the buffer has limited space and, when full, the newest data is discarded;
            //this method allows the user to empty the buffer of old data so new data is used
        float Read();
            //get a reading from the device in the set mode;
            //RequestSyncRead() must be called at least 99 ms
            //before this method can be called in a synchronous mode;
            //may be called at any time during asynchronous mode;
        operator float();
            //shorthand for taking a range reading;
            //ex: "float reading = MB1210Object;"
};

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXx PwmIn.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//mbed Microcontroller Library
//Pulse Width Modulation Input Interface
//Copyright 2010
//Thomas Hamilton

#include "PwmIn.h"

PwmIn::PwmIn(PinName pwi) : InterruptIn(pwi), PeriodMeasurement(0), PulseWidthMeasurement(1)
{
    mode(PullDown);
    rise(this, &PwmIn::PulseStart);
    fall(this, &PwmIn::PulseStop);
    start();
}

float PwmIn::read()
{
    return (float)PulseWidthMeasurement / PeriodMeasurement;
}

float PwmIn::period()
{
    return (float)PeriodMeasurement / 1000000;
}

int PwmIn::period_ms()
{
    return PeriodMeasurement / 1000;
}

int PwmIn::period_us()
{
    return PeriodMeasurement;
}

float PwmIn::pulsewidth()
{
    return (float)PulseWidthMeasurement / 1000000;
}

int PwmIn::pulsewidth_ms()
{
    return PulseWidthMeasurement / 1000;
}

int PwmIn::pulsewidth_us()
{
    return PulseWidthMeasurement;
}

void PwmIn::PulseStart()
{
    PeriodMeasurement = read_us();
    reset();
}

void PwmIn::PulseStop()
{
    PulseWidthMeasurement = read_us();
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx PwmIn.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//mbed Microcontroller Library
//Pulse Width Modulation Input Interface
//Copyright 2010
//Thomas Hamilton

#ifndef PwmInLibrary
#define PwmInLibrary

#include "stdint.h"
#include "mbed.h"

class PwmIn : private InterruptIn, Timer
{
    private:
        unsigned int PeriodMeasurement;
        unsigned int PulseWidthMeasurement;

        void PulseStart();
        void PulseStop();

    public:
        PwmIn(PinName pwi);
        float read();
        float period();
        int period_ms();
        int period_us();
        float pulsewidth();
        int pulsewidth_ms();
        int pulsewidth_us();
};

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXx main.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

#include "mbed.h"
#include "MB1210.h"

DigitalOut debugled(LED1);
Serial Computer(USBTX, USBRX);

MB1210 RangeFinder(p12, p15, p13, p14);
float Range;
int main()
{
    Computer.baud(9600);
    debugled = 0;
    RangeFinder.Unit(39.370);//change units to inches
    RangeFinder.AttachInterruptBuffer(&Range);
    RangeFinder.Mode(0x0A);
    while(1)
    {
        debugled = !debugled;
        RangeFinder.RequestSyncRead();//request a range reading
        wait_ms(100);//wait for reading to be prepared
        //RangeFinder.Mode(0);//switch to PWM mode
        //Computer.printf("PWM reading: %f in | ", Range);
        //RangeFinder.Mode(1);//switch to Analog mode
        //Computer.printf("Analog reading: %f in | ", Range);
        //RangeFinder.Mode(2);//switch to serial mode
        Computer.printf("Serial reading: %f in | ", Range);
        wait(0.9);
    }
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXx