Hello,
Any tip to help me with this project ?
Thanks
Laurent
Le dimanche 28 octobre 2018 à 16:07:02 UTC+1, Laurent FAILLIE via
Owfs-developers <[email protected]> a écrit :
Hello,
I'm trying to simulate a DS2438 with an Arduino.
But I got only errors :
RESET
44 : START CONVERSION
Measuring ...
RESET
Measurement done ...
B8 : Ignored RECALL with arg
0 : Argument
ERROR
RESET
The datasheet stats "Recall Memory [B8hxxh]
This command recalls the stored values in EEPROM / SRAM page xxh to the
scratchpad page xxh. This command must proceed a Read SPxx command in order to
read any page of memory on the DS2438."
So I understood I have to send to 1 wire bus the scratchpad content, which 9
bytes longs, right ?
The full code is :
/* Emulates a DS2438 using an SHT31
*
* Provided by Destroyedlolo. (http://destroyedlolo.info)
*
* 28/10/2018 - First version (rebuild in fact)
*/
#include <Arduino.h>
#include <LowLevel.h>
#include <OneWireSlave.h>
#define DEBUG // Comment out to be silence
/*
* 1-Wire related
*/
Pin oneWireData(2); // Where the 1-wire bus is connected to
/*
* SHT31 related
*/
#include <Wire.h>
#include "Adafruit_SHT31.h"
Adafruit_SHT31 sht31;
const byte owROM[7] = { 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 };
enum OW_Cmd {
INVALID = 0x00,
START_CONVERSION_T = 0x44,
START_CONVERSION_V = 0xB4,
RECALL = 0xB8, /* + 1byte */
READ_SCRATCHPAD = 0xBE /* + 1byte */
};
/* Temperature will be stored in ... temperature fields (1/2)
* Hydrometry will be stored in Voltages fields (3/4)
* in order to be compatible with user end software, hydrometry is scaled by
* 10 : reading "10 V" means 100% humidity.
*/
volatile byte scratchpad[9];
void scratchpadupdated( void ){ // Recalculate the checksum
scratchpad[8] = OWSlave.crc8((const byte*)scratchpad, 8);
}
/* Registers */
enum REGS {
STATUS = 0,
TEMP_LSB, TEMP_MSB,
VLT_LSB, VLT_MSB
};
/* Status register used flags */
#define STATUS_TEMPBUSY 0x10
#define STATUS_VLTBUSY 0x40
enum DeviceState {
WAIT4RESET,
WAIT4COMMAND,
WAIT4ARG,
ARG_RCVED,
STARTCONVERTION,
};
volatile DeviceState state = DeviceState::WAIT4RESET; // Current chip state
enum OW_Cmd ongoing = OW_Cmd::INVALID; // For multi-bytes command, the
command currently processed
byte arg; // Argument read
void owRcv( OneWireSlave::ReceiveEvent evt, byte cmd ){
switch( evt ){
case OneWireSlave::RE_Reset:
#ifdef DEBUG
Serial.println(F("RESET"));
#endif
state = DeviceState::WAIT4COMMAND;
ongoing = OW_Cmd::INVALID;
break;
case OneWireSlave::RE_Error:
#ifdef DEBUG
Serial.println(F("ERROR"));
#endif
state = DeviceState::WAIT4RESET;
break;
case OneWireSlave::RE_Byte:
#ifdef DEBUG
Serial.print( cmd, HEX );
#endif
if( state == DeviceState::WAIT4RESET ){
#ifdef DEBUG
Serial.println(F(" : Ignored as we are waiting for RESET"));
#endif
} else if( state == DeviceState::WAIT4ARG ){
arg = cmd;
state = DeviceState::ARG_RCVED;
#ifdef DEBUG
Serial.println(F(" : Argument"));
#endif
OWSlave.beginWrite((const byte*)scratchpad, 9, 0);
} else switch( cmd ){
case OW_Cmd::START_CONVERSION_V:
case OW_Cmd::START_CONVERSION_T:
#ifdef DEBUG
Serial.println(F(" : START CONVERSION"));
#endif
state = DeviceState::STARTCONVERTION;
break;
case OW_Cmd::RECALL:
#ifdef DEBUG
Serial.println(F(" : Ignored RECALL with arg"));
#endif
state = DeviceState::WAIT4ARG;
ongoing = (enum OW_Cmd)cmd;
break;
case OW_Cmd::READ_SCRATCHPAD:
#ifdef DEBUG
Serial.println(F(" : READ SCRATCH"));
#endif
state = DeviceState::WAIT4ARG;
ongoing = OW_Cmd::READ_SCRATCHPAD;
break;
#ifdef DEBUG
default:
Serial.println(F(" : Unknown command"));
state = DeviceState::WAIT4RESET;
#endif
}
}
}
/*
* Let's go
*/
unsigned long starttime;
void setup() {
Serial.begin(9600); // serial debugging
for(int i = 2; i<8; i++) // Initial scratchpad value
scratchpad[i] = 0;
scratchpadupdated();
starttime = 0;
OWSlave.setReceiveCallback(&owRcv);
OWSlave.begin(owROM, oneWireData.getPinNumber());
/* Has to be set AFTER OWSlave init otherwise
* the arduino will hang
*/
if( !sht31.begin(0x44)) // Start with the sht31
Serial.print(F("Can't find an SHT31\n"));
#ifdef DEBUG
Serial.print(F("Ready, waiting for 1-wire command ...\n"));
#endif
}
void loop() {
delay(10);
if( starttime && ( millis() > starttime + 19) ){ // done
starttime = 0;
sht31.retrieveMeasurements();
#ifdef DEBUG
Serial.print(F("Measurement done ...\n"));
#endif
scratchpad[STATUS] &= ~(STATUS_TEMPBUSY | STATUS_VLTBUSY);
scratchpadupdated();
} else if( state == DeviceState::STARTCONVERTION ){ // starting measure
state = DeviceState::WAIT4RESET;
sht31.startMeasurement();
starttime = millis();
#ifdef DEBUG
Serial.print(F("Measuring ...\n"));
#endif
scratchpad[STATUS] |= STATUS_TEMPBUSY | STATUS_VLTBUSY;
scratchpadupdated();
}
}
It's obviously at an early stage as I'm fighting against this nasty error :(
Thanks for your tips/
Laurent
_______________________________________________
Owfs-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/owfs-developers
_______________________________________________
Owfs-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/owfs-developers