How can my code act on multiple 1-wire sensors?

Hey Group,

This question was attached to another thread that I started, but I decided it needed its own topic in the “Device” category.

So I have been working with the example 1-wire code found here…
http://electricimp.com/docs/resources/onewire/

In the second part of the tutorial the code is changed to discover multiple attached 1-wire sensors. But the code does not (for me anyway) make it easy to act on each of the discovered sensors individually.

I would greatly appreciate assistance in modifying the code to assign each “found” sensors value to a variable that I can later test for value and act on or send specific values to the agent or to the server.log

The scenario is that I may have several temperature sensors (ds18b20’s) but only want to send the value of a specific sensor in an email or the value of a different sensor to the server.log or sound a local alarm when another sensors value exceeds a threshold.

Therefore from my perspective (experience in BASIC language only) I need to be able to test the value of a chosen sensor and to do that I need a way to name each found sensor. or is there a better way to do it??

It would be sufficient if each found sensors current value was simply assigned to ow1, ow2, ow3, etc, then I could easily act on a given sensors value.

`
foreach (device, slave_id in slaves)
{
// Run through the list of discovered slave devices, getting the temperature
// if a given device is of the correct family number: 0x28 for BS18B20

    if (slave_id[7] == 0x28)
    {
        one_wire_reset();
        
        // Issue 1-Wire MATCH ROM command (0x55) to select device by ID
        
        one_wire_write_byte(0x55);
        
        // Write out the 64-bit ID from the array's eight bytes
        
        for (local i = 7 ; i >= 0; i--)
        {
            one_wire_write_byte(slave_id[i]);
        }
        
        // Issue the DS18B20's READ SCRATCHPAD command (0xBE) to get temperature
        
        one_wire_write_byte(0xBE);
        
        // Read the temperature value from the sensor's RAM
        
        temp_LSB = one_wire_read_byte();
        temp_MSB = one_wire_read_byte();
        
        // Signal that we don't need any more data by resetting the bus
        
        one_wire_reset();

        // Calculate the temperature from LSB and MSB
        
        temp_celsius = ((temp_MSB * 256) + temp_LSB) / 16.0;

        server.log(format("Device: %02d Family: %02x Serial: %02x%02x%02x%02x%02x%02x Temp: %3.2f", (device + 1), slave_id[7], slave_id[1], slave_id[2], slave_id[3], slave_id[4], slave_id[5], slave_id[6], temp_celsius));
    }
}

`

Guidance, direction, code snippets, any form of enlightenment, all appreciated.
This squirrel is a real challenge for a newbie

thanks in advance.
dwight

If it’s specific sensors you want to read, you’ll need to try each one on their own to get their unique ID - the value that gets dropped into the the slave_id[] array. With that information, you can get readings from each sensor and save that reading in a Squirrel table with the 1-Wire ID as one value and the temperature (or whatever) reading as a second value. Tables access values through keys, so set it up with keys id and reading.

` // Initialize a global array to hold the sensors and their data
sensorArray <- []

// Create a table to hold the sensor ID and its initial reading
local sensor = {}
sensor.id <- sensorIDstring
sensor.reading <- sensorReadingFloat

sensorArray.append(sensor)

. . .

// X seconds later, change the value

foreach (sensor in sensorArray)
{
// Run through all the sensors in the array
// When we find the one we want, change its value

if (sensor.id == currentSensorID) sensor.reading = currentSensorReading

}
`

Squirrel tables store key-value pairs - you access a specific value by providing the key. So now you run through your sensors, and send the value:

`foreach (index, sensor in sensorArray)
{
// Run through all the sensors in the array
// When we find the one we want, send its value to the agent for emailing

if (sensor.id == targetSensorID) agent.send(“emailvalue”, sensor)
}`

You’ll need a device.on(“emailvalue”, emailFunction) in your agent code. emailFunction is a function you write to email the value. The function will need a single parameter into which the message data is passed, eg.

`emailFunction(sensorData)
{
local valueToEmail = sensorData.reading

. . . 

}`

FWIW, Dwight, I learned to program using Basic. Squirrel is not a million miles away from modern Basic (when I learned, you had to use line numbers). Take a look at the Squirrel Programming Guide - this should help you get to grips with Squirrel and help you understand sample code until you find your feet.

thanks smitty,

That gives me something to chew on… I will spend some time with the code this weekend and ask further questions as they (inevitably will) come up.

These imp’s are amazing!

Thanks for the help
dwight

@smittytone, forgive the dumb question, but does this code you list above get inserted into the original 1-wire tutorial code you provided at a specific place?

And, I’m assuming it cannot be inserted “as-is”, but requires some modifications?

I just got done with a few days of playing with relays and finally understand. Now I want to use the 1-wire sensors to write equipment control stuff. Like @impulsepower, code is not my strength and if you have time to write a few sentences about where this updated code gets placed (if important) and what portions require modification (can’t be used as-is), it would be wonderful. In fact, beyond wonderful.

Have a great weekend!

yes Please help us understand :slight_smile:
This squirril is a bit (lot) daunting!

I still would think if the code could just assign each “found” sensor to a “serialized” variable then if one had 4 sensors attached the variables could just be ow1, ow2, ow3, ow4. (I know… the code can do what ever one is capable of programming)

Then one could just touch each sensor and see which value changes to identify each sensor.

@Smitty, in your example above are you saying that one will need to determine the serial number of each sensor and then individually enter that into the code to be able to read each sensor and assign it to the table along with the read value.

thanks for any help/direction

No, I’m saying (IIRC) that you read each sensor in, and save its serial ID in a variable. To make it more generic - in case you add a sensor - the code above shows how to store the serial IDs in a table, but you could do ow1, ow2, ow3 etc instead. Only then you have to change the code if you add or remove sensors.

Warming one sensor and not the others will allow you to show its specific ID. All 1-Wire devices have a unique ID.