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

Reply via email to