Howdy Everyone,
I am trying to take real-time data using a H3LIS331DL accelerometer I got from controleverything.com.
I’m currently using this code;
// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// H3LIS331DL
// This code is designed to work with the H3LIS331DL_I2CS I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/content/Accelorometer?sku=H3LIS331DL_I2CS#tabs-0-product_tabset-2
#include <application.h>
#include <spark_wiring_i2c.h>
// H3LIS331DL I2C address is 0x18(24)
#define Addr 0x18
int xAccl = 0, yAccl = 0, zAccl = 0;
void setup()
{
// Set variable
Particle.variable("i2cdevice", "H3LIS331DL");
Particle.variable("xAccl", xAccl);
Particle.variable("yAccl", yAccl);
Particle.variable("zAccl", zAccl);
// Initialise I2C communication as MASTER
Wire.begin();
// Initialize serial communication, set baud rate = 9600
Serial.begin(9600);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control register 1
Wire.write(0x20);
// Enable X, Y, Z axis, power on mode, data output rate 50Hz
Wire.write(0x27);
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control register 4
Wire.write(0x23);
// Set full scale, +/- 100g, continuous update
Wire.write(0x00);
// Stop I2C Transmission
Wire.endTransmission();
delay(300);
}
void loop()
{
unsigned int data[6];
for(int i = 0; i < 6; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((40 + i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 6 bytes of data
// xAccl lsb, xAccl msb, yAccl lsb, yAccl msb, zAccl lsb, zAccl msb
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
delay(300);
}
// Convert the data
int xAccl = ((data[1] * 256) + data[0]);
if(xAccl > 32767)
{
xAccl -= 65536;
}
int yAccl = ((data[3] * 256) + data[2]);
if(yAccl > 32767)
{
yAccl -= 65536;
}
int zAccl = ((data[5] * 256) + data[4]);
if(zAccl > 32767)
{
zAccl -= 65536;
}
// Output data to dashboard
Particle.publish("Acceleration in X-Axis is :", String(xAccl));
Particle.publish("Acceleration in Y-Axis is :", String(yAccl));
Particle.publish("Acceleration in Z-Axis is :", String(zAccl));
delay(300);
}
The data is currently being output to the Dashboard but that is much too slow for taking accurate measurements in real time.
I’m looking to output the data to a file (instead of to the dashboard), and increase the data output rate (currently set to 50hz and don’t know how to change).
Any help is very very appreciated. Thank you!
-Alex
@goondry, Particle.publish() has a 1 publish/second rate limit and trying to publish! If you want to send data out at 50Hz, you will need to send the data using TCP or UDP directly.
2 Likes
@peekay123 Thank you for the reply! I am currently working on establishing the TCP connection and sending data, but I’m running into a Usage Error (5 red blinks after sos). Here is what I have done
#include "Particle.h"
#include <application.h>
#include <spark_wiring_i2c.h>
// H3LIS331DL I2C address is 0x18(24)
#define Addr 0x18
SYSTEM_MODE(MANUAL);
int serverPort = 5001;
byte server[] = {xxxxxxxxx};//server's ip address
char clientmsg0[60] =" Data Stream Successful to o ";
char clientmsg1[60] =" Data Stream Successful to 1 ";
char clientmsg2[60] =" Data Stream Successful to 2 ";
TCPClient client;
//Begin Sensor Code
int xAccl = 0, yAccl = 0, zAccl = 0;
void out(const char *s) {
client.write( (const uint8_t*)s, strlen(s) );
}
void setup1(){
// Set variable
Particle.variable("i2cdevice", "H3LIS331DL");
Particle.variable("xAccl", xAccl);
Particle.variable("yAccl", yAccl);
Particle.variable("zAccl", zAccl);
// Initialise I2C communication as MASTER
Wire.begin();
// Initialize serial communication, set baud rate = 9600
Serial.begin(9600);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control register 1
Wire.write(0x20);
// Enable X, Y, Z axis, power on mode, data output rate 50Hz
Wire.write(0x27);
//Enable X, Y, Z axis, power on mode, data output rate 1000Hz
//Wire.write(0x3F)
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control register 4
Wire.write(0x23);
// Set full scale, +/- 100g, continuous update
Wire.write(0x00);
// Stop I2C Transmission
Wire.endTransmission();
delay(300);
}
void stream() {
while (client.connected()){
void loop(){
unsigned int data[6];
for(int i = 0; i < 6; i++){
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((40 + i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 6 bytes of data
// xAccl lsb, xAccl msb, yAccl lsb, yAccl msb, zAccl lsb, zAccl msb
if(Wire.available() == 1){
data[i] = Wire.read();
}
delay(300);
}
out(clientmsg1);
// Convert the data
int xAccl = ((data[1] * 256) + data[0]);
if(xAccl > 32767){
xAccl -= 65536;
}
int yAccl = ((data[3] * 256) + data[2]);
if(yAccl > 32767){
yAccl -= 65536;
}
int zAccl = ((data[5] * 256) + data[4]);
if(zAccl > 32767){
zAccl -= 65536;
}
// //Still need to scale output
// // Output data
client.printf("x Acceleration Data:",xAccl);
client.println();
client.printf("y Acceleration Data:",yAccl);
client.println();
client.printf("z Acceleration Data:",zAccl);
client.println();
out(clientmsg2);
}
}
}//stream
void setup(){
while (!WiFi.ready()) {
Particle.process();
WiFi.connect();
while(WiFi.connecting()){
Particle.process();
}
}// while (!WiFi.ready())
client.connect(server, serverPort);
stream();
}//setup()
I just have no idea what the problem is now, especially since the code compiles.
Thank you for any help,
-Alex
First, drop these includes, they are not required
#include <application.h>
#include <spark_wiring_i2c.h>
Then I’d change this
void setup() {
// replace
// while (!WiFi.ready()) {
// Particle.process();
// WiFi.connect();
// while(WiFi.connecting()){
// Particle.process();
// }
// }// while (!WiFi.ready())
// with
WiFi.connect();
waitUntil(WiFi.ready);
Particle.process();
client.connect(server, serverPort);
stream();
}//setup()
Why are you not putting the functionality of stream()
(minus the wrapping while()
) into loop()
?
And why on earth have you got void loop()
inside that while()
in void stream()
???
BTW, if you use int16_t
instead of int
you can drop that if (x > 32767)
stuff.
like
int16_t xAccl = (data[1] << 8) | data[0];
You are also hiding the global variables xAccl
/ yAccl
/ zAccl
with local ones of the same name.
And I’d also only send one TCP packet like this
client.printf("x Acceleration Data: %d\r\n"
"y Acceleration Data: %d\r\n"
"z Acceleration Data: %d\r\n"
,xAccl,yAccl,zAccl);
And I’m not entirely sure that’s the way you’d read that sensor either.
I’m pretty sure you’d only set the address once and then read all 6 registes in one go.
And where is your Wire.begin()
in your code? (apart from the never executed setup1()
)
2 Likes
@ScruffR Thank you for your comments I went through and made the changes you suggested! Most of the stuff in that code was a 4am last ditch effort to make it work, but now I think the code is much closer to working correctly.
The issue I’m running into now is the device is disconnecting from the internet every time I try to flash the code (LED blinks slowly green). Here is what I have.
#include "Particle.h"
// H3LIS331DL I2C address is 0x18(24)
#define Addr 0x18
//Just Added
SYSTEM_MODE(MANUAL);
int serverPort = 5002;
byte server[] = {192, 168, 0, 104.};//server's ip address
TCPClient client;
void send(const char *s) {
client.write( (const uint8_t*)s, strlen(s) );
}
void setup()
{
// Set variable
//Particle.variable("i2cdevice", "H3LIS331DL");
//Particle.variable("xAccl", xAccl);
//Particle.variable("yAccl", yAccl);
//Particle.variable("zAccl", zAccl);
// Initialise I2C communication as MASTER
Wire.begin();
// Initialize serial communication, set baud rate = 9600
Serial.begin(9600);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control register 1
Wire.write(0x20);
// Enable X, Y, Z axis, power on mode, data output rate 50Hz
Wire.write(0x27);
//Enable X, Y, Z axis, power on mode, data output rate 1000Hz
//Wire.write(0x3F)
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control register 4
Wire.write(0x23);
// Set full scale, +/- 100g, continuous update
Wire.write(0x00);
// Stop I2C Transmission
Wire.endTransmission();
delay(300);
//Just Added
//From Forum
WiFi.connect();
waitUntil(WiFi.ready);
Particle.process();
client.connect(server, serverPort);
}
void loop()
{
unsigned int data[6];
for(int i = 0; i < 6; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((40 + i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 6 bytes of data
// xAccl lsb, xAccl msb, yAccl lsb, yAccl msb, zAccl lsb, zAccl msb
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
delay(300);
}
// Convert the data
int16_t xAccl = ((data[1] << 8) | data[0]);
int16_t yAccl = ((data[3] << 8) | data[1]);
int16_t zAccl = ((data[5] * 256) + data[4]);
//Still need to scale output
// Output data to dashboard
//Particle.publish("Acceleration in X-Axis is :", String(xAccl));
//Particle.publish("Acceleration in Y-Axis is :", String(yAccl));
//Particle.publish("Acceleration in Z-Axis is :", String(zAccl));
char clientmsg[60];
sprintf(clientmsg, "X Acceleration Data is %d", xAccl);
send (clientmsg);
delay(300);
}
Any ideas on why it is doing this? Thank you!
-Alex
Yes, I do know why.
You are using SYSTEM_MODE(MANUAL)
but don't connect to the Particle cloud (Particle.connect()
) but even if you did, you don't maintain the connection by regularly calling Particle.process()
.
OTA flashing is a Particle cloud action.
1 Like