odd behaviour with two subscribers

Started by jimh

jimh

Hi Alain,

As the testing continues I have come across another odd piece of behaviour which I am not sure is a coding problem or something else.

This is the code I have been testing:

/*
Name: nctemp.ino
Created: 12/22/2018 11:20:15 AM
Author: jimha
*/

#include #include #include #include #include #include #include

#define DHTPIN 2 // Pin which is connected to the DHT sensor.

// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)

// See guide for details on sensor wiring and usage:
// https://learn.adafruit.com/dht/overview

DHT_Unified dht(DHTPIN, DHTTYPE);

const int ledPin = LED_BUILTIN;
// Variables will change:
//int ledState = LOW; // ledState used to set the LED

String sensoreName;

NocanChannelId tid; // temperature
NocanChannelId hid; // humidity
NocanChannelId lid; // led
NocanChannelId mid; // motion

Timer<> timer;

bool read_sensors(void *) {

sensors_event_t event;

dht.temperature().getEvent(&event);
if (isnan(event.temperature)) {
	// error handler
}
else {

	String temp_string;

	temp_string = String(event.temperature, 2);            // transform temp into string

	Nocan.publishMessage(tid, temp_string.c_str());        // publish to the network
}

// Get humidity event and print its value.
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) {
	// error handler
}
else {

	String temp_string;

	temp_string = String(event.relative_humidity, 2);      // transform humidty into string

	Nocan.publishMessage(hid, temp_string.c_str());        // publish to the network

}

return true; // repeat? true }

// move message processing to its own function
void process_msg() {

NocanMessage msg;

int8_t status = Nocan.receiveMessage(&msg);

if (status == 0)
{
	
	if (msg.channel_id == lid)   // handle the led message
	{
		if (msg.data[0] == 'c' || msg.data[0] == '1')
			digitalWrite(ledPin, HIGH);
		if (msg.data[0] == 'o' || msg.data[0] == '0')
			digitalWrite(ledPin, LOW);
	}
	else if (msg.channel_id == mid)  // handle the motion message - way setup this should turn the led on but not off on motion msg
	{
		if (msg.data[0] == 'c' || msg.data[0] == '1')
			digitalWrite(ledPin, HIGH);
		if (msg.data[0] == 'o' || msg.data[0] == '0')
			digitalWrite(ledPin, LOW);
	}
} }

// the setup function runs once when you press reset or power the board
void setup() {

// set the digital pin as output:
pinMode(ledPin, OUTPUT);

// Initialise Nocan
for (;;)
{
	if (Nocan.open() >= 0)
		break;  // Nocan open success
	delay(1000);
}

int8_t lookUpStatus;
// lookup channel name and register if not found
lookUpStatus = Nocan.lookupChannel("myled", &lid);
if (lookUpStatus < 0) { // lookup a failed, channel not registered
	Nocan.registerChannel("myled", &lid);
}

lookUpStatus = Nocan.lookupChannel("temperature", &tid);
if (lookUpStatus < 0) { // lookup a failed, channel not registered
	Nocan.registerChannel("temperature", &tid);
}

lookUpStatus = Nocan.lookupChannel("humidity", &hid);
if (lookUpStatus < 0) { // lookup a failed, channel not registered
	Nocan.registerChannel("humidity", &hid);
}

lookUpStatus = Nocan.lookupChannel("motion", &mid);
if (lookUpStatus < 0) { // lookup a failed, channel not registered
	Nocan.registerChannel("motion", &mid);
}

// subscribe to channels of interest
Nocan.subscribeChannel(lid);
Nocan.subscribeChannel(mid);

// Initialize sensor device.
dht.begin();
sensor_t sensor;
sensoreName = sensor.name;

// call the read_sensors function every 60 seconds
timer.every(60000, read_sensors);

}

// the loop function runs over and over again until power down or reset
void loop() {

timer.tick(); // tick the timer

if (Nocan.receivePending())
{
	process_msg();
} }

If I comment out this block:

lookUpStatus = Nocan.lookupChannel("motion", &mid);
if (lookUpStatus < 0) { // lookup a failed, channel not registered
	Nocan.registerChannel("motion", &mid);
}

The built-in led responds to
nocanc publish myled 1/0 but won't respond to nocanc publish motion 0/1

If I uncomment the block the reverse occurs:

The built-in led responds to
nocanc publish motion 1/0 but won't respond to nocanc publish myled 0/1

It is like only the last workable subscribe actually works.

Is the process_msg function the right way to process channels to obtain the channel data in order to act differently to messages on on different channels that are subscribed? We need to be able to differentiate up to 12 subscribed channels.

The sensors are being read and published fine it is only the handling of the subscribed channels that is the current issue.

Best regards,
Jim

Alain

Hi Jim,

Well this is a pretty embarrassing bug on our side. We tested multiple subscribed channels many times during developpement, but it seems there was regression during the final release after the kickstarter.

We will update the Arduino library in the next following days, so that all users can get a corrected version automatically through the Arduino board manager.

Until the library is available, an immediate fix is to edit the Arduino libraries as follows:

1) First locate the NoCAN Arduino directory:

  • On a Mac/Linux machine, this should be in ~/Library/Arduino15/packages/Omzlo/hardware/samd/0.1.0/libraries/NOCAN
  • On a windows machine it should be in
    C:\Users(username)\AppData\Local\Arduino15\packages\Omzlo\hardware\samd\0.1.0\libraries\NOCAN

2) edit the file nocan_ll.c in that directory, and insert the line of code right after line 307:

            channel_filters[filter] = channel_id; 

The surrounding code should look like this:

            spi_begin();
            spi_transfer(SPI_NOCAN_FILTER_COMMIT);
            spi_transfer(filter);
            spi_end();

            channel_filters[filter] = channel_id;
            // TODO: read back
            return RETCODE(NOCAN_LL_OK);
     }

This should provide you with the ability for each node to open up to 11 channels (this is one short of your 12 channel requirement.)

Best regards,

Alain

jimh

Hi Alain,

Added the fix to nocanc_ll.c and can confirm the code now acts as expected. I will continue to test and if any issues show up I will let you know.

Best regards,
Jim