Skip to content
This repository has been archived by the owner on Jan 7, 2019. It is now read-only.

Driver and example for AMSYS 5915 pressure sensor #275

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/stm32f4_discovery/pressure_amsys5915/SConstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# path to the xpcc root directory
xpccpath = '../../..'
# execute the common SConstruct file
execfile(xpccpath + '/scons/SConstruct')
120 changes: 120 additions & 0 deletions examples/stm32f4_discovery/pressure_amsys5915/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// coding: utf-8
/* Copyright (c) 2017, Raphael Lehmann
* All Rights Reserved.
*
* The file is part of the xpcc library and is released under the 3-clause BSD
* license. See the file `LICENSE` for the full license governing this code.
*/
// ----------------------------------------------------------------------------

#include <xpcc/architecture/platform.hpp>

#include <xpcc/processing.hpp>
#include <xpcc/driver/pressure/amsys5915.hpp>
#include <xpcc/io/iostream.hpp>
#include <xpcc/debug/logger.hpp>

xpcc::IODeviceWrapper< Usart2, xpcc::IOBuffer::BlockIfFull > device;

// Set all four logger streams to use the UART
xpcc::log::Logger xpcc::log::debug(device);
xpcc::log::Logger xpcc::log::info(device);
xpcc::log::Logger xpcc::log::warning(device);
xpcc::log::Logger xpcc::log::error(device);

// Set the log level
#undef XPCC_LOG_LEVEL
#define XPCC_LOG_LEVEL xpcc::log::DEBUG

/**
* Example to demonstrate a XPCC driver for pressure sensor AMSYS 5915
*
* This example uses I2cMaster2 of STM32F407
*
* SDA PB11
* SCL PB10
*
* GND and +3V are connected to the sensor.
*/

typedef I2cMaster2 MyI2cMaster;
// typedef xpcc::SoftwareI2cMaster<GpioB10, GpioB11> MyI2cMaster;

xpcc::amsys5915::Data data;
xpcc::Amsys5915<MyI2cMaster> pressureSensor(data);

class ThreadOne : public xpcc::pt::Protothread
{
public:
bool
update()
{
PT_BEGIN();

XPCC_LOG_DEBUG << "Ping the device from ThreadOne" << xpcc::endl;

// ping the device until it responds
while (true)
{
// we wait until the task started
if (PT_CALL(pressureSensor.ping())) {
break;
}
// otherwise, try again in 10ms
this->timeout.restart(10);
PT_WAIT_UNTIL(this->timeout.isExpired());
}

XPCC_LOG_DEBUG << "Device responded" << xpcc::endl;

while (true)
{
while (! PT_CALL(pressureSensor.readPressure()))
{
PT_YIELD();
}

XPCC_LOG_INFO << "Pressure [0..1]: " << data.getPressure() << xpcc::endl;
XPCC_LOG_INFO << "Temperature [degree centigrade]: " << data.getTemperature() << xpcc::endl;

// read next pressure measurement in 1ms
this->timeout.restart(1);
PT_WAIT_UNTIL(this->timeout.isExpired());
}

PT_END();
}
private:
xpcc::ShortTimeout timeout;
};

ThreadOne one;

// ----------------------------------------------------------------------------
int
main()
{
Board::initialize();

GpioOutputA2::connect(Usart2::Tx);
Usart2::initialize<Board::systemClock, xpcc::Uart::B115200>(10);

GpioB11::connect(I2cMaster2::Sda);
GpioB10::connect(I2cMaster2::Scl);

MyI2cMaster::initialize<Board::systemClock, 400000>();

XPCC_LOG_INFO << "\n\nWelcome to AMSYS 5915 pressure sensor demo!\n\n";

xpcc::ShortPeriodicTimer tmr(500);

while (1)
{
one.update();
if (tmr.execute()) {
Board::LedOrange::toggle();
}
}

return 0;
}
3 changes: 3 additions & 0 deletions examples/stm32f4_discovery/pressure_amsys5915/project.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
board = stm32f4_discovery
buildpath = ${xpccpath}/build/stm32f4_discovery/${name}
131 changes: 131 additions & 0 deletions src/xpcc/driver/pressure/amsys5915.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// coding: utf-8
/* Copyright (c) 2012, Niklas Hauser
* Copyright (c) 2017, Raphael Lehmann
* All Rights Reserved.
*
* The file is part of the xpcc library and is released under the 3-clause BSD
* license. See the file `LICENSE` for the full license governing this code.
*/
// ----------------------------------------------------------------------------

#ifndef XPCC_AMSYS5915_HPP
#define XPCC_AMSYS5915_HPP

#include <xpcc/architecture/interface/i2c_device.hpp>
#include <xpcc/math/utils/endianness.hpp>

namespace xpcc
{

// forward declaration for friending with amsys5915::Data
template < typename I2cMaster >
class Amsys5915;

struct amsys5915
{
struct xpcc_packed
Data
{
template < typename I2cMaster >
friend class Amsys5915;

public:
/**
* This method returns the pressure as a normalized float from 0-1.
* You have to scale and offset this according to the specific sensor
* you have.
* So if you have AMS 5915-0010-D, you can measure +10mBar, you need to
* multiply it with 10.0f to get the pressure in mBar.
* If you have AMS 5915-0350-D-B, which can measure ±350mBar you first need to
* subtract 0.5f and then multiply it with 350.0f!
*/
float
getPressure()
{
// mask undefined bits
data[0] &= 0b00111111;
// Full scale span is 13107, with offset 1638
uint16_t *rData = reinterpret_cast<uint16_t*>(data);
uint16_t pressure = xpcc::fromBigEndian(*rData) - 1638;
return static_cast<float>(pressure) / 13107.f;
}

/**
* This method returns the temperature of the pressure sensor in °C.
*/
float
getTemperature()
{
uint16_t temperatureRaw = (data[3] >> 5) | (static_cast<uint16_t>(data[2]) << 3);
return ((temperatureRaw * 200.f) / 2048.f) - 50.f;
}
private:
// 0: MSB
// ..
// 3: LSB
uint8_t data[4];
};
};

/**
* Driver for the AMSYS 5915 differential and absolute pressure sensors.
*
* The device runs a cyclic program, which will store a corrected pressure value with
* 12 bit resolution about every 500 μs within the output registers of the internal ASIC.
*
* Datasheet: http://www.amsys.de/sheets/amsys.de.ams5915.pdf
*
* @ingroup driver_pressure
* @author Raphael Lehman, Niklas Hauser
*/
template < typename I2cMaster >
class Amsys5915 : public amsys5915, public xpcc::I2cDevice<I2cMaster, 1, I2cReadTransaction>
{
public:
/**
* @param data a amsys5915::Data object
* @bug The address of the sensor is by factory default set to 0x28.
* This means you cannot use two AMSYS 5915 sensors on the same bus!
* You have to use a MUX or two seperate I2C busses.
*/
Amsys5915(Data &data)
: I2cDevice<I2cMaster,1,I2cReadTransaction>(0x28), data(data)
{
this->transaction.configureRead(data.data, 4);
}

/// pings the sensor
xpcc::ResumableResult<bool>
ping()
{
RF_BEGIN();

RF_WAIT_UNTIL(this->transaction.configurePing() and this->startTransaction());

RF_WAIT_WHILE( this->isTransactionRunning() );

this->transaction.configureRead(data.data, 4);

RF_END_RETURN( this->wasTransactionSuccessful() );
}

/// reads the Pressure registers and buffers the results
inline xpcc::ResumableResult<bool>
readPressure()
{
return this->runTransaction();
}

public:
/// Get the data object for this sensor.
inline Data&
getData()
{ return data; }

private:
Data &data;
};

} // namespace xpcc

#endif // XPCC_AMSYS5915_HPP