General area when it fits no where else

Moderator: Mmiscool

User avatar
By livetv
#55170 @Phil,

Take a look here. This is the C code that I think will plug into the interpreter.

Code: Select all// the following 3 declarations need to be made somewhere to have them available for both functions.
byte devAddr[8];   // create 8 byte storage area for device code
String junk="";      // Need a place to compile results or process code "halves"
byte index;      // Just any old counter

// The rest can be plugged into the interpreter code right after the temp() function handler:

 else if ( fname == F("temp_ids") && num_args == 0 ) {
    // function temp_ids()
    // Return all connected sensor ROM codes as space-separated string (16 characters each)
    junk="";
    for (index=0; sensors.getAddress(deviceAddr,index); index++)   // Loop while devices are found
    {
        if (index>0) junk.concat(" ");               // If not the first device, add a separator space
        junk.concat(String(*((uint32_t *)devAddr), HEX);    // Convert & append the first 4 bytes of device code
        junk.concat(String(*((uint32_t *)(&devAddr[4])), HEX);   // Convert and append the last 4 bytes of device code
    }
    *value_str = junk;
    return PARSER_TRUE;
  }


 else if ( fname == F("temp_by_id")  && num_args == 1 ) {
    // function temp_by_id( {Rom Code} )   Rom code is a 16 character hexadecimal string
    sensors.requestTemperatures();   // Tell all sensors to convert analog to digital
    junk=args_str[0].substring(0,7);   // Get first 8 characters and...
    junk.strtoul(devAddr, NULL, 16);   //  ... convert them to the first 4 code bytes
    junk=args_str[0].substring(8);   // Do the same with the remaining 8 bytes
    junk.strtoul(&devAddr[4], NULL, 16);
    *value = sensors.getTempC(devAddr);   // Perform the temperature read by device code
    return PARSER_TRUE;
  }


I'm proposing adding two functions:

TEMP_IDS() queries all devices to return their ROM codes. It works exactly like TEMP() with no arguments but returns one long string with all ROM codes present. Presumably, you would ID each sensor alone on the wire and physically label it, not having to deal with this command except in a discovery utility.

TEMP_BY_ID( {ROM Code} ) would send a request to a particular sensor and report its reading, just like TEMP() does. Since it only addresses one, the wire is not clogged with all other responses and if we do get a response, we know exactly who it is from.

As I write this, it occurs to me that we should add only the TEMP_BY_ID() function and have it perform the ROM code discovery role if no ROM code is given as an argument. Like this:

Code: Select allelse if ( fname == F("temp_by_id") && num_args == 0 ) {
    if ( num_args == 0 ) {
        // Perform ROM code discovery here as outlined above
        }
      else {
        // Perform normal temperature query by the supplied ROM code as outlined above
        }
    }



This cuts one function out of the language which is becoming pretty large. The interpreter has a very long chain of "elseif" conditionals in its command decoder. Whenever a command or function is decoded, this is a very long ordeal, slowing down the interpreter considerably. To change this to something much faster would require an overhaul of the whole interpreter. Needless to say, the less we add to it the better.