Closed MintyMods closed 2 years ago
I have a bundle if Grove stuff. I'll swing by the lab this afternoon and see if there is a TH02 in there I can try to replicate with.
Are any of your other devices using i2c and do they work ok?
Let us know how it goes with standardFirmata.
Hi Dtex,
I also have a Whitelabs Tenticle Shield with PH, EC and temperature circuits which are I2C and these seem to work correctly using the following addresses:-
const I2C_ATLAS_PH_SENSOR_ADDR = (0x63);
const I2C_ATLAS_EC_SENSOR_ADDR = (0x64);
const I2C_ATLAS_TEMP_SENSOR_ADDR = (0x66);
These are being used via the board.i2cReadOnce
so not sure it is a valid comparison
// Communicate with the Atlas Tenticle Shield, Motor Shields, etc via I2C
sendI2C = function(channel, command, callback) {
console.log('I2C[' + channel + '] Sending Command: ' + command);
board.io.i2cWrite(channel, command);
board.wait(ATLAS_DELAY, function() {
board.i2cReadOnce(channel, ATLAS_BYTES_TO_READ, function(bytes) {
console.log('I2C[' + channel + '] Result: ' + decode(bytes));
callback(bytes);
});
});
};
I also have a Grove MotorBoard and Ada Fruit MotorBoard running at the following address:-
const I2C_GROVE_MOTORBOARD_ADDR = (0x14);
const I2C_ADAFRUIT_MOTORBOARD_A_ADDR = (0x60);
const I2C_ADAFRUIT_MOTORBOARD_B_ADDR = (0x70);
But to be honest other than connecting them to resolve any address conflicts I have not actually run any motors via them yet as not being able to read humidity and temperature puts a stop to my (Hydroponic) project so I kind of got tunnel locked into that.
I will test using the I2C motor boards with my current configuration and then test all scenarios against StandardFirmata and report back.
Thank you so much for the support.
OK, tested against StandardFirmata
and all tests behaved identical to when run against ConfigurableFirmata
(apart from the RF433 scenarios which are only supported by ConfigurableFirmata
and my reason for using it).
I noticed that the temperatures / humidity values being reported when the TH02 sensor is not even connected are the same as I originally reported:-
// Values reported when TH02 not connected
[1] Thermometer
[1] celsius : -50
[1] fahrenheit : -58
[1] kelvin : 223.15
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : -24
[1] --------------------------------------
So it seems the I2C sockets on the Grove Base Shield are not working? I have tried each of the four sockets and tried multiple different Grove leads without luck.
I am not really sure how to debug that further apart from purchasing another Grove Base Shield which is going to take a few days to arrive.
One possible idea I have is to use the breakout section of the AdaFruit Motor Board v2 to solder a Grove Socket/Header (which I did purchase) and connect this to the standard Arduino pins for 5v, Gnd, SCL, SDA which I am guessing would allow me to connect a single device for testing?
Going to start by RTFM/Google for the base shield and see where that takes me but I now doubt this is Johnny-Five issue but will leave it open for a while just so I can document anything I find that might help others hitting the same problem.
I am very noob to this Hardware journey but so excited to be able to control it using JavaScript.
Thank you again for your help.
Rather than mess with the motor board I just cut one of the grove cables in half, tinned the ends and connected directly to the Arduino with the same results. Johnny-Five reports as if the TH02 is not connected while running the demo TH02 code works and produces valid results:-
/*
* Demo name : TH02_dev demo
* Usage : DIGITAL I2C HUMIDITY AND TEMPERATURE SENSOR
* Author : Oliver Wang from Seeed Studio
* Version : V0.1
*/
#include <TH02_dev.h>
#include "Arduino.h"
#include "Wire.h"
void setup()
{
Serial.begin(9600); // start serial for output
Serial.println("****TH02_dev demo by seeed studio****\n");
/* Power up,delay 150ms,until voltage is stable */
delay(150);
/* Reset HP20x_dev */
TH02.begin();
delay(100);
/* Determine TH02_dev is available or not */
Serial.println("TH02_dev is available.\n");
}
void loop()
{
float temper = TH02.ReadTemperature();
Serial.println("Temperature: ");
Serial.print(temper);
Serial.println("C\r\n");
float humidity = TH02.ReadHumidity();
Serial.println("Humidity: ");
Serial.print(humidity);
Serial.println("%\r\n");
delay(1000);
}
Gives the following correct results:-
Temperature:
27.25C
Humidity:
54.19%
Thanks for doing all that. I did not have a TH02 in my box of Grove stuff so I'll have to order one. I'll see if I have any of those other sensors at home tonight. The fact that you can't get a valid value out of any of those leads me to believe it may indeed by a J5 error... we'll see.
I feel bad making you purchase a Grove TH02 to help me trouble shoot was could potentially be a mistake on my side and I really appreciate the help so If I can donate a TH02 in anyway I would be willing to do so?
Also just to clarify my original comment about the sensors so as not to miss lead you.
I have tried the BME280 sensor example using a kit obtained from Amazon KeeYees BME280 but this only had 4 pins rather than 8 so I connected it to GND, 5v, SCL & SDA via a grove cable plugged directly into the Grove Base Shield.
Running the following J5 example code:-
const I2C_BME280_SENSOR_ADDR = (0x76);
var multi = new five.Multi({
controller: "BME280",
address: I2C_BME280_SENSOR_ADDR
});
multi.on("change", function() {
console.log(" celsius : ", this.temperature.celsius);
console.log(" fahrenheit : ", this.temperature.fahrenheit);
console.log(" relative humidity : ", this.hygrometer.relativeHumidity);
console.log("--------------------------------------");
});
Produces the following incorrect results:-
[1] >> Johnny-Five Board Init - COM7
[1] Thermometer
[1] celsius : 215
[1] fahrenheit : 419
[1] kelvin : 488.15
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : 0
[1] --------------------------------------
Running the following example code BMx280_I2C.ino from Arduino UI (comments and whitespace removed)
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
BMx280I2C bmx280(I2C_ADDRESS);
void setup() {
Serial.begin(9600);
while (!Serial);
Wire.begin();
if (!bmx280.begin()) {
Serial.println("begin() failed. check your BMx280 Interface and I2C Address.");
while (1);
}
if (bmx280.isBME280())
Serial.println("sensor is a BME280");
else
Serial.println("sensor is a BMP280");
bmx280.resetToDefaults();
bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
if (bmx280.isBME280())
bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}
void loop() {
delay(1000);
if (!bmx280.measure()) {
Serial.println("could not start measurement, is a measurement already running?");
return;
}
do {
delay(100);
} while (!bmx280.hasValue());
Serial.print("Pressure: "); Serial.println(bmx280.getPressure());
Serial.print("Pressure (64 bit): "); Serial.println(bmx280.getPressure64());
Serial.print("Temperature: "); Serial.println(bmx280.getTemperature());
if (bmx280.isBME280()) {
Serial.print("Humidity: ");
Serial.println(bmx280.getHumidity());
}
}
Produces the following correct results (I guess, not sure how 'high' I am :0)
Pressure: 101296.00
Pressure (64 bit): 0.00
Temperature: 25.97
Humidity: 35.78
The DH11
& DH22
I have not actually tested yet (Sorry for any confusion) as these needed a Nano Backpack and I was not clear on how to make these as the resister confused me and I need it to wire it into the Grove Base Shield so I just decided to go with the TH02 example which looked 'Plug-N-Play' :o)
I did purchase the following hardware and can test these sensors (I just need to read up on resisters first) but the newer sensors I presume are better?
I also just spotted this BME680 which looks awesome but I am bit reluctant to buy anymore Grove hardware at the moment as my project is totally committed to Johnny-Five but for me at least - Grove seems to be a problem.
I don't know if it makes a difference but this is the Arduino I purchased which was a cheap alternative from China.
Leonardo R3 ATmega32U4 Development Board With USB Cable Geekcreit for Arduino - products that work with official Arduino boards
The issue seems to be around the TH02 conversion promise within imu.js
which is always resolving with values of [0,0]
TH02: {
... snipped ...
conversion.then(function() {
Promise.all([
new Promise(function(resolve) {
io.i2cReadOnce(address, 0x01, 1, function(data) {
resolve(data[0]);
});
}),
new Promise(function(resolve) {
io.i2cReadOnce(address, 0x02, 1, function(data) {
resolve(data[0]);
});
})
]).then(function(data) {
===> Always resolves to [0,0]
The following comment against that function is interesting:-
// Both values will be placed in the 0x01 after // the command is received and the measurement taken. // The datasheet _SAYS_ read the MSB and LSB from 0x01 and 0x02, // but in reality, reading from 0x01 produces nothing. Trial and // error testing resulted in discovering the correct data located // in 0x02 & 0x03. // // One might assume that we could then read 2 bytes from 0x02, // but that also produces garbage, so in the end we need to read // 3 bytes from 0x01.
Checking the code from the working Grove example show it seems to be using an array of 3 and discarding the first value:-
uint16_t TH02_dev::TH02_IIC_ReadData2byte() {
uint16_t TempData = 0;
uint16_t tmpArray[3] = {0};
int cnt = 0;
TH02_IIC_WriteCmd(REG_DATA_H);
Wire.requestFrom(TH02_I2C_DEV_ID, 3);
while (Wire.available()) {
tmpArray[cnt] = (uint16_t)Wire.read();
cnt++;
}
/* MSB */
TempData = (tmpArray[1] << 8) | (tmpArray[2]);
return TempData;
}
So as a test I hacked imu.js
to do what I think the comments suggests
conversion.then(function() {
Promise.all([
new Promise(function(resolve) {
io.i2cReadOnce(address, 0x01, 3, function(data) {
resolve(data[1],data[2]);
});
}),
]).then(function(data) {
Which gave me a result although not a very accurate one (actual temp was 26.7 and humidity 40%)
[1] TH02 Thermometer
[1] celsius : 26
[1] fahrenheit : 78.8
[1] kelvin : 299.15
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : 58
[1] --------------------------------------
[1] TH02 Thermometer
[1] celsius : 26
[1] fahrenheit : 78.8
[1] kelvin : 299.15
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : 57
[1] --------------------------------------
Regarding the Grove Motor Board not working, I don't think the one I have is compatible with the GROVE_I2C_MOTOR_DRIVER
controller as the one I have is a version one and is marked with TB6612FNG
on the back.
I managed to get it working within Arduino using the following:-
#include "Grove_Motor_Driver_TB6612FNG.h"
#include <Wire.h>
MotorDriver motor;
void setup()
{
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
Serial.begin(9600);
motor.init();
}
void loop()
{
// drive 2 dc motors at speed=255, clockwise
Serial.println("run at speed=255");
motor.dcMotorRun(MOTOR_CHA, 255);
motor.dcMotorRun(MOTOR_CHB, 255);
delay(1000);
// brake
Serial.println("brake");
motor.dcMotorBrake(MOTOR_CHA);
motor.dcMotorBrake(MOTOR_CHB);
delay(1000);
// drive 2 dc motors at speed=200, anticlockwise
Serial.println("run at speed=-200");
motor.dcMotorRun(MOTOR_CHA, -200);
motor.dcMotorRun(MOTOR_CHB, -200);
delay(1000);
// stop 2 motors
Serial.println("stop");
motor.dcMotorStop(MOTOR_CHA);
motor.dcMotorStop(MOTOR_CHB);
delay(1000);
}
I did try modifying the motor.js
based on the code from Seed Studio but kind of got lost in the API for J5 in terms of how pins are being used with I2C boards. The GROVE_I2C_MOTOR_DRIVER
seems to be implemented using setPWM
and setPin
to determine speed and direction although the API from Seed Studio shows a run method that sets both speed and direction within the same I2C write while specifying which motor channel to work with.
void MotorDriver::dcMotorRun(motor_channel_type_t chl, int16_t speed) {
if (speed > 255) {
speed = 255;
} else if (speed < -255) {
speed = -255;
}
if (speed >= 0) {
_buffer[0] = GROVE_MOTOR_DRIVER_I2C_CMD_CW;
} else {
_buffer[0] = GROVE_MOTOR_DRIVER_I2C_CMD_CCW;
}
_buffer[1] = chl;
if (speed >= 0) {
_buffer[2] = speed;
} else {
_buffer[2] = (uint8_t)(-speed);
}
I2Cdev::writeBytes(_addr, _buffer[0], 2, _buffer + 1);
delay(1);
}
All good fun :)
Regarding TH02: That's good detective work!
Which gave me a result although not a very accurate one (actual temp was 26.7 and humidity 40%)
Are these roughly the same value you get when running the sample Grove code?
So as a test I hacked imu.js to do what I think the comments suggests
I found the commit where it switched from reading 3 bytes beginning at 0 to reading bytes from 1 and 2 separately.
Would you like to contribute and submit a fix?
Note: I have a nagging worry that reading from any register position other than 0 isn't working. This has nothing to do with J5 or any specific device. We've fixed some other reported errors in J5 by switching to read from 0 and dropping unnecessary bytes instead of reading from a specific register position. Since the error would be in firmata, J5 tests would never have caught it and it would be working on every other platform. It really would explain a lot (but is a separate issue from this).
Regarding the Grove Motor Board:
Ya, it looks like the register locations to write to are completely different and a new controller needs to be added for this board.
Regarding TH02: That's good detective work!
Thanks, I have been watching a few Johnny-Five presentations on YouTube and the enthusiasm you guys have for J5 is addictive.
Are these roughly the same value you get when running the sample Grove code?
The temperature was not to far out with Actual = 26.7
and J5 TH02 reporting = 26
but the humidity is way out with Actual = 40%
and J5 TH02 reporting 58%
on one tick and 57%
on the next etc.
I found the commit where it switched from reading 3 bytes beginning at 0 to reading bytes from 1 and 2 separately.
Would you like to contribute and submit a fix?
Yes, I would love to get involved but not sure my hack is the correct fix at the moment so would need to do a little more digging around first. The commit link you posted is not returning any results for me so let me look back at the commit history to see the changes.
Note: I have a nagging worry that reading from any register position other than 0 isn't working. This has nothing to do with J5 or any specific device. We've fixed some other reported errors in J5 by switching to read from 0 and dropping unnecessary bytes instead of reading from a specific register position. Since the error would be in firmata, J5 tests would never have caught it and it would be working on every other platform. It really would explain a lot (but is a separate issue from this).
Thanks for the hint, I will have another look around.
Regarding the Grove Motor Board:
Ya, it looks like the register locations to write to are completely different and a new controller needs to be added for this board.
I have moved this into a separate issue to make tracking easier.
Back to the TH02 - I have played around a little and found the following code changes to imu.js
resolve the issue (for me at least) and the results are now consistent with the example TH02_demo
from Grove/Arduino UI.
I have submitted a PR #1660 for review and there seems to be two parts to this change:-
0x01
rather than a single byte from 0x01
& 0x02
. uint16(data[0], data[1])
as this resulted in no precision within the results (e.g. temperature would change from 25 to 26 rather than hitting 25.1, etc). The results seem good now and the change event is also firing correctly now it is producing decimal places.
Values reported via Johnny-five example from the original post (starts of with an initial negative read but quickly corrects itself):-
[1] >> Johnny-Five Board Init - COM7
[1] TH02 Thermometer
[1] celsius : -50
[1] fahrenheit : -58
[1] kelvin : 223.15
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : 57.69
[1] --------------------------------------
[1] TH02 Thermometer
[1] celsius : 27.3
[1] fahrenheit : 81.14
[1] kelvin : 300.45
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : 57.69
[1] --------------------------------------
[1] TH02 Thermometer
[1] celsius : 27.3
[1] fahrenheit : 81.14
[1] kelvin : 300.45
[1] --------------------------------------
[1] Hygrometer
[1] relative humidity : 57.63
[1] --------------------------------------
Values reported via Serial Monitor in Arduino running Grove TH02_demo:-
Temperature:
27.06C
Humidity:
58.19%
Temperature:
27.03C
Humidity:
58.31%
Temperature:
27.03C
Humidity:
58.25%
I can't reproduce that initial negative read so will ignore for now...
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Hello everyone,
I’m encountering an issue with the Grove Temperature and Humidity Sensor (High Accuracy AndMini-v1.0) when using it with an Arduino Uno. The sensor is giving me strange readings - it shows -50.00°C for temperature and -24.00% for humidity.
I’ve checked my code and connections, but I’m still getting these incorrect values. Has anyone else experienced this issue before? If so, do you know what might be causing it and how to fix it?
This is the code I used :
#include <TH02_dev.h>
#include “Arduino.h”
#include “Wire.h”
#include “THSensor_base.h”
#define ShowSerial Serial
#ifdef AVR
#include <SoftwareSerial.h>
SoftwareSerial SSerial(2, 3); // RX, TX
#define COMSerial Serial
#define ShowSerial Serial
TH02_dev TH02;
#endif
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define COMSerial Serial1
#define ShowSerial SerialUSB
TH02_dev TH02;
#endif
#ifdef ARDUINO_ARCH_STM32F4
#define COMSerial Serial
#define ShowSerial SerialUSB
TH02_dev TH02;
#endif
void setup() {
ShowSerial.begin(9600); // start serial for output
ShowSerial.println("****TH02_dev demo by seeed studio****\n");
/* Power up,delay 150ms,until voltage is stable */
delay(150);
/* Reset HP20x_dev */
TH02.begin();
delay(100);
/* Determine TH02_dev is available or not */
ShowSerial.println("TH02_dev is available.\n");
}
void loop() {
float temper = TH02.ReadTemperature();
ShowSerial.print("Temperature: ");
ShowSerial.print(temper);
ShowSerial.println("C\r\n");
//Serial.print("%\t");
float humidity = TH02.ReadHumidity();
ShowSerial.print("Humidity: ");
ShowSerial.print(humidity);
ShowSerial.println("%\r\n");
delay(1000);
}
I appreciate any help or insights you can provide!
Thank you.
Hi,
Could someone provide me with some assistence as I seem to have hit a dead end with trying to get temperature and humidity reading via Johnny-Five.
I have tried numerous different sensors (TH02, BME280, DH11, DH22) and I can not get a valid reading out of any of them when used with Johnny-Five. I am sure this is something I am doing wrong but do not really know how to debug the issue further.
Bsaically running the following Johnny-five sample produces incorrect results for my testing with an Arduino Leonardo:-
The output I receive is as follows:-
The change event only fires once which I guess is because the reading are not changing (this I can confirm by using the
'ondata'
event rather than the'onchange'
) and seeing the same incorrect readings being output.The TH02 is connected via I2C as per the diagram from the API docs. I have verified the I2C channel to be the default
(0x40)
as shipped by Grove and I have checked the J5 source code for IMU which shows it is also using address 0x40.Checking the code against the source code from seed studio for the TH02 suggests it is not an issue with the Johnny-five TH02 IMU module as both contain the same formula etc.
The sensor and hardware seem fine and running the sample code provided with the sensor does produce valid readings with temperature about 26 celsius and humidity about 38%.
I am using ConfigurableFirmata rather than StandardFirmata as I require support for sending RF433 codes so it may be possible there is an issue here and I will try to test again against StandardFirmata.
I have seen various other posts/issues where the readings are correct or at least not minus figures so suspect this must be something I am doing or that the TH02 support is not compatible with the Leonardo?
Any help is greatly appreciated as I have already put a lot of work into using Johnny-five for my solution and all the other aspects (motors, RF senders, relays, etc) are all working as expected.
Thank you.