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 Owfs-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/owfs-developers