Dealing with DYP-ME007Y TX spurious readings

The serial-output of the DYP-ME007Y ultrasonic range detector is pretty good when you are measuring the distance to a static object with little or no other obstacles creating ‘noise’.

However, the odd spurious reading does crop in from time to time. For example:

201cm
201cm
201cm
128cm
201cm
201cm
201cm
201cm
201cm
201cm

This is actual data, and the spurious 128cm makes no sense and needs to be ignored (rather than just taking an average). Fortunately, @JMMS-Karunarathne and @MikeMeinz wrote some code to correct for this here: https://www.codeproject.com/tips/813946/a-method-to-ignore-anomalies-in-an-ultrasonic-dist

The code takes a group of samples and counts how many of each there are. It then picks the measurement with the highest count (the ‘mode’). In the above example, there are 9 counts of 201cm – which would be returned as the measurement.

So far, so good..

However, there is a problem where all the data is rubbish. Look at this actual data:

275cm
273cm
273cm
275cm
0cm
483cm
0cm
0cm
125cm
235cm
274cm
274cm
274cm
690cm
816cm
274cm
274cm
273cm
0cm
483cm
0cm
274cm
274cm
90cm
184cm
292cm
273cm
539cm
648cm
316cm

This was produced by out-of-range measurements – the object was less than 28cm from the sensor. The measurement which occurred the most was 274cm and so the algorithm would return this seemingly meaningful result.

An improvement to the ‘mode’ routine would be to apply a ‘confidence’ to the measurement. In my code, I take 30 readings, and require a minimum of 20 of the same to accept it as a good measurement. I try this five times over, after which the routine gives up and returns a zero indicating out-of-range. This seems to work well.

Except some of the time. This looks like good data:

82cm
82cm
82cm
82cm
83cm
82cm
82cm
83cm
83cm
83cm
83cm
83cm
83cm
83cm
83cm
82cm
83cm
83cm
83cm
82cm
82cm
83cm
82cm
83cm
82cm
80cm
83cm
83cm
82cm
82cm
confidence was 16
Returning 0cm

Here 83cm was only measured 16 times. This was an absolutely static measurement on the bench, however the returned value was either 82 or 83cm (ignoring the 1x 80cm!).

The way to deal with this is to look at the readings +1 or -1 from the mode. If either the count of the mode, added to the count of the mode+1, or mode-1 adds up to at least the threshold, then the result is good.

 

DYP-ME007Y TX (Serial output) Ultrasonic Sensor interfacing with Arduino / NodeMCU

There are two main versions of the DYP-ME007Y ultrasonic module (see here to tell the difference) – this article is about interfacing and taking readings from the serial output version.

At the labs, we have been working on interfacing one of these with the NodeMCU – an Arduino-type device with built-in Wifi. This is in order to create a water tank level sensor. The automotive ultrasonic sensor lends itself to this application in that there is no need to add waterproofing – it is already there.

To interface with it we need to convert the 3.3V digital in/outs from the NodeMCU to the 5V required by the DYP-ME007Y. If you were using a 5V Arduino, you wouln’d have to do this. For us, we use a bi-directional logic level converter which is available from eBay. We bought from Electro TV Parts because they stock them in the UK and so shipping is fast.

We are only using two of the four channels on the converter. These are for the two sides of the serial connection between the NodeMCU and the DYP-ME007Y – RX and TX. The converter also needs 5V, 3.3V and GND, which are all available on a pins of the NodeMCU board.

On the NodeMCU, we then need to choose two digital pins for the serial connection, and connect these to the LV (low voltage) side of the converter. The HV side connects to the DYP-ME007Y RX and TX pins. It also needs 5V and GND.

For the serial connection, the pin assigned as TX on the NodeMCU connects (via the converter) to the RX pin on the DYP-ME007Y, and RX on the NodeMCU to TX on the DYP-ME007Y, also via the converter. That’s just how serial works!

Now on to the coding.

We use SoftwareSerial to assign the two digital pins as the TX and RX on the NodeMCU, then we are ready to read the results from the DYP-ME007Y.

#include <SoftwareSerial.h>

// pin assignments. TX on the arduino connects to RX on the sensor, RX to TX.
#define TX_PIN D3
#define RX_PIN D4

SoftwareSerial DYPSensor = SoftwareSerial(RX_PIN, TX_PIN);
const int MAX_TRY_SERIAL = 50; // how many cycles of 10ms to wait for before giving up on the sensor (up to 255)

Here you can see I am using pre-defined constants (D3/D4) for the NodeMCU in the Arduino dev environment. We also define how many times we will try to read the serial before giving up. This allows trapping of the situation were there is nothing coming from the DYP-ME007Y – like if it was not connected.

Now in setup, we start up the serial:

void setup() {

 Serial.begin(19200);
 delay(10);

 DYPSensor.begin(9600);

} // end of setup

We are also starting up the serial connection to the computer it is connected to so we can see debug information.

Our loop looks like this:

void loop() {

 int current_reading;
 current_reading = GetDistance();

 Serial.print(current_reading);
 Serial.println("cm");

 delay(50);
}

..which just calls a subroutine to read the sensor and then prints the result to serial.

GetDistance looks like this:

int GetDistance() {
 byte msb, lsb, checksum, checkcalc, tries = 0;
 int distance;

// we want a 255 which is the start of the reading (not msb but saving a byte of variable storage)..
 while (msb != 255) {
 // wait for serial..
 while ( not DYPSensor.available() && tries < MAX_TRY_SERIAL ) {
 delay(10);
 tries++;
 }
 if (tries == MAX_TRY_SERIAL) {
 Serial.println(" TIMED OUT WAITING FOR SERIAL.");
 return -1;
 }
 msb = DYPSensor.read();
 }

// now we collect MSB, LSB, Checksum..
 while ( not DYPSensor.available() ) {
 delay(10);
 }
 msb = DYPSensor.read();

while ( not DYPSensor.available() ) {
 delay(10);
 }
 lsb = DYPSensor.read();

while ( not DYPSensor.available() ) {
 delay(10);
 }
 checksum = DYPSensor.read();

// is the checksum ok?
 checkcalc = 255 + msb + lsb;

if (checksum == checkcalc) {
 distance = msb * 256 + lsb;
 // Round from mm to cm
 distance += 5;
 distance = distance / 10;

return distance;
 } else {
 Serial.println("bad checksum - ignoring reading.");
 return -1;
 }

} // end of GetDistance()

GetDistance() returns a signed integer of the distance in cm, or -1 if it returned bad data, or the serial read timed out.

It works like this:

  1. Keep reading until we receive a 0xFF which is the start byte.
  2. Now read the most significant byte (msb).
  3. Read the least significant byte (lsb).
  4. Read the checksum.
  5. Calculate the checksum and compare to the one sent from the device.
  6. If checksum matches, it’s a good reading and so return it. If not, return -1.

It makes no attempt to decide whether the sensor has actually sent a meaningful result, just that what we received matched what it sent. More of validating the results in a later article.

Here is the code in full:

 

/*
 Reads a DYP-ME007Y TX ultrasonic sensor and writes the distance to serial.
 This is the SERIAL VERSION of the sensor
*/

#include <SoftwareSerial.h>

// pin assignments. TX on the Arduino connects to RX on the sensor, RX to TX.
#define TX_PIN D3
#define RX_PIN D4

SoftwareSerial DYPSensor = SoftwareSerial(RX_PIN, TX_PIN);

const int MAX_TRY_SERIAL = 50; // how many cycles of 10ms to wait for before giving up on the sensor (up to 255)

void setup() {

Serial.begin(19200);
 delay(10);

 DYPSensor.begin (9600);

} // end of setup


//
// Reads bytes from RX port and returns a reading in cm

int GetDistance() {
 byte msb, lsb, checksum, checkcalc, tries = 0;
 int distance;

// we want a 255 which is the start of the reading (not msb but saving a byte of variable storage)..
 while (msb != 255) {
 // wait for serial..
 while ( not DYPSensor.available() && tries < MAX_TRY_SERIAL ) {
 delay(10);
 tries++;
 }
 if (tries == MAX_TRY_SERIAL) {
 Serial.println(" TIMED OUT WAITING FOR SERIAL.");
 return -1;
 }
 msb = DYPSensor.read();
 }

// now we collect MSB, LSB, Checksum..
 while ( not DYPSensor.available() ) {
 delay(10);
 }
 msb = DYPSensor.read();

while ( not DYPSensor.available() ) {
 delay(10);
 }
 lsb = DYPSensor.read();

while ( not DYPSensor.available() ) {
 delay(10);
 }
 checksum = DYPSensor.read();

// is the checksum ok?
 checkcalc = 255 + msb + lsb;

if (checksum == checkcalc) {
 distance = msb * 256 + lsb;
 // Round from mm to cm
 distance += 5;
 distance = distance / 10;

return distance;
 } else {
 Serial.println("bad checksum - ignoring reading.");
 return -1;
 }

} // end of GetDistance()



void loop() {

int current_reading;
 current_reading = GetDistance();

Serial.print(current_reading);
 Serial.println("cm");

delay(50);
}

 

DYP-ME007Y Ultrasonic distance sensor – PWM or Serial?

In order to build a tank level monitoring device, we recently bought a pile of DYP-ME007Y ultrasonic devices. We chose the single sensor version with the automotive sensor used for car parking distance when mounted on the bumper.

Having tried to use both the manual ‘pulse-trigger then measure the response’ and NewPing code, we gave up.

It turns out that there are two (well, actually three) different versions of this module, and it is not that obvious which one is which.

The two versions are Pulse Width Modulation (PWM) and Serial.

The PWM one requires a trigger input to fire it and this flashes the LED once. You then read the pulse from the Echo output.

The Serial version constantly takes readings, and outputs a distance value in mm in serial. The constant readings result in a flashing LED as soon as you apply power.

So – simple test when you apply power only:

No flashes – PWM version

Flashes – Serial version

The PWM version is well-documented, and easy to interface with on Arduino using the NewPing library but the Serial version is not. There is no way of telling from the markings on the board as these show the pin assignments for both versions.

For specification, look for the DYP-ME007TX which shows:

  • Supply voltage 5 v
  • Global Current Consumption 15 mA
  • Ultrasonic Frequency 40k Hz
  • Maximal Range 400 cm
  • Minimal Range 3 cm
  • Resolution 1 cm
  • Baud rate 9600 n,8,1
  • Outline Dimension 43x20x15 mm

However, our testing shows with the automotive sensor the minimum distance is 30cm.

Also useful is the spec of the output which is four 8-bit bytes:

  1. 0xFF: frame start marker byte.
  2. H_DATA: distance data of high eight.
  3. L_DATA: distance data of low 8 bits.
  4. Checksum byte: Value should equal 0xFF + H_DATA + L_DATA  (only lowest 8 bits)

Sonos CR200 dead spot fault – is it home-repairable?

Sonos CR200 dead pileIf you don’t want to read on, the short answer is ‘no’.

I have had a number of CR200 Sonos controllers fail with the ‘dead spot’ fault. This is a common fault on these controllers, the other being the ‘ghost touch’ fault where the controller appears to be operated by a ghost when noone is near it. It is not fun to be woken up in the middle of the night by loud music in your bedroom when this happens! It seems like these two problems have caused Sonos to abandon manufacturing their own controllers; you can only control their system with either their desktop app on your computer, or an iOS or Android app on a phone/tablet.

Sonos CR200 update screenBack to the ‘dead spot’ fault. This is where areas of the controller stop responding to touch in some areas. It mostly seems to affect the lower areas of the screen, making it impossible to view the playlist, use the back button etc. When it affects the bottom row, it is impossible to upgrade your controller as it needs you to press ‘Next’ to continue. This renders the controller useless. (If only they had a way of reducing the screen display area to move the buttons, or flipping the screen when you turned the controller upside down.)

 

So, I thought I would see if it was possible to fix this myself. If you have ever taken apart an LCD calculator, it has a connection between the glass LCD display and the circuit board made of conductive rubber which can be cleaned and reassembled. I was hoping for this type of thing..

Inside CR200Disassembly starts with the battery cover and battery. There are two screws which hold the rear cover in place. One has a tamper-proof label over it so Sonos can see if you have been meddling with it.

Undo the two screws and then the white plastic cover can be lifted away at the top and then withdrawn from the metal chassis at the bottom.

 

Inside a Sonos CR200Here is what it looks like inside. There are two membrane cables with zero-insertion-force connectors. The longer one on the bottom right is for the screen, and the one at the bottom left is for the touch.

These both have black levers which when lifted up allow the cables to be removed easily. Once this is done, the circuit board can be released at the top-centre where it is clipped into the plastic and lifted away. There is one remaining connection to the speaker at the bottom. In my case, the speaker came away from the base so it didn’t need undoing.

Touch screen connections inside Sonos CR200Once the circuit board is removed, you have the screen, which now be lifted out. You can now see the touch screen circuit around the edge of the glass and the connections from the glass to the membrane wiring and controller chip.

So, the touch resolution of the screen is really low, and so one row or column failing will render the touch function useless – with a resolution even as low as double this it could cope with a row or column failure. The membrane for the touch is bonded to the screen and so there is nothing further that can be done.

Summary: Other than to marvel at the excellent design of the metal case and internals, there is no point in ever taking a CR200 apart. The dead-spot touch failure is either in the tracks in the glass (unlikely), their connections to the membrane or the controller chip. Given that the failures seem to happen in commonly used areas, it is possibly a design fault in the controller chip (like lack of sufficient over-voltage protection). The glass appears bonded to the metal case and so you can’t even swap it out. What a shame Sonos didn’t invest in fixing this. I still prefer their controllers to an iOS app.

Freedomotic logging for development and debugging Part 2

Ok, so now we have all our log messages coded in, with appropriate log levels like warn, info, debug. How do we control where they are sent, and how much we want to see?

Freedomotic  uses log4j to handle its logging output and the config file is at framework/freedomotic-core/src/main/resources/log4j.properties

The default at the moment is to log to the console but I want to log some to the console, and some to syslog. While I am developing, the console should show me important errors from all parts of the application and the output to syslog should show me the most granular output of the module I am working on, but also what was sent to the console. This allows me to see any important errors to do with my interactions with other parts of the application straight away on the console where I started the application, but also to see them in-line with my more detailed errors/debugging log via syslog.

Here is my log4j config:

# root logger
log4j.rootLogger=WARN, sysout, SYSLOG

# Output to console
log4j.appender.sysout=org.apache.log4j.ConsoleAppender
log4j.appender.sysout.threshold=WARN
log4j.appender.sysout.layout=org.apache.log4j.PatternLayout
log4j.appender.sysout.layout.ConversionPattern=%-5p <%t> [%C{1}]: %m%n

# Output to Syslog
log4j.appender.SYSLOG=org.apache.log4j.net.SyslogAppender
log4j.appender.SYSLOG.threshold=DEBUG
log4j.appender.SYSLOG.syslogHost=localhost
log4j.appender.SYSLOG.facility=local1
log4j.appender.SYSLOG.facilityPrinting=false
log4j.appender.SYSLOG.layout=org.apache.log4j.PatternLayout
log4j.appender.SYSLOG.layout.conversionPattern=%p <%t> [%C]: %m%n

# Detailed logging of my plugin
log4j.logger.com.freedomotic.plugins.devices.emoncms=DEBUG, SYSLOG
log4j.additivity.com.freedomotic.plugins.devices.emoncms=false
  • Root logger defines all the places I want to log to, and what starting level to send there. I have it set to WARN which means sysout and SYSLOG will get all messages of levels Warning or Error (since I am not expecting levels Critical, Alert or Emergency from my application – they are for the operating system).
  • The Console Appender is defined with a maximum level of WARN. This means that if I were to alter the root logger to DEBUG, I would still only get WARN and worse to it.
  • The Syslog Appender is defines with a maximum level of DEBUG, which means any log entry can potentially get there.
  • I am sending to the syslog facility ‘local1’ on localhost which I have configured in my syslog config to go to its own file (for tidyness).
  • My conversionPattern of ‘%p <%t> [%C]: %m%n’ is slightly different to what I have seen everywhere else on the internet (clue – it has a colon) and is specifically to stop a formatting error which messes up some entries when syslogging on my Mac. (I was getting spurious ‘Unknown’ and some truncation.)
  • The ‘log4j.additivity.com.freedomotic.emoncms=false’ line basically means don’t double-up messages – only add them if they aren’t already there.

So, now I can debug by tailing my log, or better still I can deal with more awkward problems with my favourite log tool, Splunk:

Splunk log analysis

Freedomotic logging for development and debugging

Debug logOut of the box, Freedomotic logging output currently goes to the console. When you start the application, you see a whole load of messages streaming past you on the screen – very messy.

For me, the logging output should go to a file or what I mean really is that it should be sent to syslog. Ultimately, this is the best way to log applications because putting it into a system designed just for logging means you get access to all the things build specifically for dealing with logging. That probably makes no sense, but I will try to explain by way of my setup.

But firstly, lets look at how the logging happens in Freedomotic. Here is an example of some code from my Resol DL2 plugin:

 LOG.info("Loading Resol DL2 devices..");

..and its easy to see this creates the output of my informative text to the log. Actually I am telling the plugin something else – I have set the log level of ‘info’ which is important too. When you write to the log, you always specify what level you want. Here are the log levels, and Apple’s suggested usage:

  • Emergency (level 0) – The highest priority, usually reserved for catastrophic failures and reboot notices.
  • Alert (level 1) – A serious failure in a key system.
  • Critical (level 2) – A failure in a key system.
  • Error (level 3) – Something has failed.
  • Warning (level 4) Something is amiss and might fail if not corrected.
  • Notice (level 5) – Things of moderate interest to the user or administrator.
  • Info (level 6) – The lowest priority that you would normally log, and purely informational in nature.
  • Debug (level 7) – The lowest priority, and normally not logged except for messages from the kernel.

So, in my case the message is ‘purely informational in nature’ – which it is. But why would I want to log this information? Won’t I be filling the log with pointless chatter?

Now, here is the good bit with proper logging inside an application. I can code in whatever log information at whatever level and then at runtime I can decide what logs I want output from the application.  This means I can put debugging log entries in the code and have these enabled for debugging, but turned off when I am not interested in seeing them.

Next lets see how how this is done..

Eight pointers to help you fix your Sonos for big buildings

Sonos FamilyTaking a working Sonos system and moving to a bigger house should be simple. Sonos ‘just works’, right?

Well, away from the Labs I moved house last year to somewhere with a bit more space. The Sonos came with me and the first zone was unpacked early on the morning after the move as we began the unboxing. Since then it has never worked properly.. until this week.

Over the months I have tried various things to attempt to cure the drop-outs, unresponsive controllers and general grief. Here us some useful info to help anyone in the same situation:

1. SonosNet doesn’t like airwave congestion.

Sonos Preferences - AdvancedSonosNet is the built-in wireless networking of the Sonos system (although you can also get it to use your own wifi now). SonosNet is effectively a private, hidden wifi network and operates in the same air-space as your own wifi, DECT mobile phones and other wireless devices in the same waveband. For this reason, you should ensure your SonosNet is not on the same channel as your Wifi. It is simple to set this from the desktop controller preferences screen. Choices are Chanel 1, 6 or 11 and your Wifi should also be on one of these three.

2. Your wired connections aren’t necessarily being used.

Just because you have added wired connections either between Sonos components, or back to your router / switch doesn’t mean Sonos is using them. The next two points relate to this.

3. Sonos tries to keep ‘hops’ to a minimum, doesn’t necessarily use nodes you think it will.

It seems like Sonos components only like to be a maximum of two hops from each other. This means that if you try to improve coverage by adding say a Bridge Sonos Connect between two other components, it will ignore it because it would add another hop and therefore more latency.

4. Sonos uses Spanning Tree Protocol, so your network switch has to play nicely with this.

This is a bit network-engineer-techy. Because a Sonos system can have multiple connection paths between components, it needs a way to decide which one it will use – and it will only use one path at any given time. It uses something called Spanning Tree Protocol (or STP for short) to do this. If you have components connected via a network switch (which would include one built into your router if it has multiple network ports) then it has to play nicely with STP. By this I mean it either has to implement STP (eg. a managed switch), or pass STP information between connected devices. If it doesn’t do either of these, Sonos will ignore your wired network for connecting Sonos components together and just use SonosNet. Also bear in mind that the STP cost may have to be adjusted, depending on the STP protocol your switch is using.

5. If you have any wired connections, it will be using SonosNet, not your wifi.

'About my Sonos System' screen

‘About my Sonos System’ screen

The recent additional option of connecting your Sonos to your Wifi means that you no longer need the first Sonos component to be wired to your router (or network). However, if any of your Sonos components have a wired connection, the whole system will revert back to SonosNet automatically. This is not obvious – the controller won’t tell you. The best way to confirm this is with the desktop controller – go to ‘About my Sonos System’ which shows you a list of your components. There is an option called WM – 0 means SonosNet, 1 means Wifi. If the Sonos component switches from one to the other, it will reboot. I have seen a component connected via a dodgy network cable continually switch between the two, rebooting each time.

6. Your Sonos system provides diagnostics (but they are not really for you to look at).

Sonos components provide a web interface which can give you a better picture of what is going on. Find the IP of a component using the ‘About my Sonos System’ screen above. Then connect to: http://<your IP:1400/support/review for example on my system: http://192.168.1.102:1400/support/review

On a large system (or one with dodgy networking) this can take a while to return a page, or if your system is really bad, it can fail altogether some of the time. The page will show a list of your components, each of which can be expanded to list a whole load of stuff, most of which I ignore. There are two particularly useful diagnostics though.

At the bottom of the list is Network Matrix. This gives a tabular view of your Sonos components. Each one is listed along the top and down the left of the table. Here is what mine looks like now (ignore the undefined columns which are components currently turned off):

Screen Shot 2014-11-07 at 11.31.51

 

Some important points to look for on your matrix.

  • Look at the colours – green is best, then yellow, orange, and worst is red. These are quality of wireless network to/from the device. An all-grey column/row indicates no wireless connections on that component. You may get for a wired component which is not participating in the SonosNet.
  • Look at the Inbound / Outbound numbers. They give signal strength and go up to 64. Low numbers are worst.
  • Coloured squares in the matrix show what is wirelessly connected to what. This will give you an idea of the path your music data takes.
  • There should only be one empty box per row/column on the matrix. This is where the same component meets on the row/column. If you have more empty boxes, then you have communication problems. Take a look at this matrix. The signal strength is all ok, but there are more blanks than there should be. This will (and does) result in drop-outs, controller delays etc.:

Sonos matrix

7.  Any one poor link in the mesh has the ability to affect the whole system.

Each Sonos zone has a media player which tries to maintain ‘subscriptions’ to all other media players. Also each controller tries to keep tabs of what each zone is up to (think about the Zones screen). If you have one badly connected zone, this will cause problems somewhere, whether its playback, poor controller response etc. The last matrix shows a system in a state where this happens. Everything works great for a while, then picking up a CR200 controller results in playback drop-out from a zone wired directly to the NAS!

8. Sonos provides ongoing support – and its good.

Sonos support have seen all this stuff before, and with access to the diagnostics can pinpoint problems. There is a built-in mechanism for getting this diagnostics to them – the ‘About my Sonos System’ screen (shown above in point 5) has a ‘Submit DIagnostics’ button. This will capture the state of the system and can be used straight after you have a problem to help Sonos Support.

Finally..

From learning all this, out of the many things I tried, I think these are the steps which made it all work in the end:

1. Install a managed switch. Set the STP cost on the Sonos ports to 10 (for 100Mbps) from the default of 19.

2. Wire network connections from the switch to key Sonos components at various points around the house.

3. Make sure the home Wifi was not on the same channel as the Sonos. I ended up with Sonos on 6, and Wifi on 1 and 11 (one at each end of the house).

 Happy Listening!

Ubiquiti Unifi AP-LR repair

We have had a couple of ‘frisbees’ – the excellent Ubiquiti Unifi access points knocking around which were broken. Unusually, they run on 24V POE rather than the more common 48V. One of the minions here in the Labs didn’t realise this and tried to power them straight from a switch with 48V. They broke.

Unifi_ap

The symptoms were that the power supply light would only flash periodically in sync with an orange light in the device. Unplug the ethernet cable from the frisbee and the PSU light comes on solid. This says power supply is fine, frisbee is broken.

There is precious little information on these devices about fixing them, other than a few people who have done the same as us. The usual answer is ‘its broken – buy another’.

On opening the device (4x torx screws), there is no evidence of damage – no black marks, charring, exploded components to give any clues as to the failure.

One comment I read talked about protection diodes which could be the cause. Looking at the circuit board, the power track from the ethernet connector goes to a voltage regulator chip, and on its way, there are some capacitors to ground and a large surface mount diode labelled ‘D1’. The markings on it are ‘129’ and ‘GEZ’. A little research shows this is a SMCJ24A which is a ‘transient voltage suppressor’ or TVS. GEZ is actually the identification of 24V working voltage rating used by Lite-On Semiconductor. This component is there to ‘clamp’ the voltage if it goes above 24V (actually somewhere between 26.7 and 29.5V) in order to protect the more sensitive circuits from voltage spikes (or people plugging in the wrong POE). In our case it had done its job in protecting the rest of the board, but has partially failed in that it won’t pass 24V for any length of time.

Location of D1 on Unifi AP-LR

It is not too difficult to remove D1 using a soldering iron and some long nosed pliers. Plugging in the board with D1 removed shows it works, but D1 is there to protect from spikes and so it is a good idea to replace it. The component costs pence each and is available from RS Components here. When soldering it back in, make sure you get it the correct way round; there is a line on the top at one side – this goes away from the edge of the board – towards the top on the picture above.

Update:

We have two broken APs – with D1 removed, both of them light the LED D29 which indicates power, and both have 3.3V on the JTAG port. One of them shows network activity when the ethernet port is plugged into the network – LED D30 flashes, but the other does nothing else. Sometimes LED D25 (the yellow/green one) lights up orange when it is powered up, sometimes not. I think this one is definitely for the bin. The other one has a working boot loader. If you power it on whilst holding the reset button down, D25 goes green after about 5 seconds, and then cycles orange/green/off after 10+. I think it does need the BIOS reinstalling though..

For anyone following this, I suggest removing D1 (even by cutting it in two with side cutters) and then powering up. You can then assess the condition of the rest of the board before sourcing the replacement TVS. These things aren’t that expensive, so no point in wasting loads of time on it..

Using emoncms for eco-eye data

emoncms is the data storage, graphing and general visualisations for the OpenEnergyMonitoring project.

For some time here at the Labs we have been using Xively for the data collection and graphing of our energy usage and other sensor stuff. It has really good graphing, plus excellent debug console for checking the incoming data. Beyond this, we have not really been making the best use of it.

We have now switched to emoncms for data collection and graphing. This will give us a better ability to graph multiple feeds together and in any case we will be moving to their sensors at some point in the future.

Their system is open source, so we could choose to host/run our own data collection/storage/graphing but for now an account with them will do. At a later date we can choose to migrate by downloading all our data from them.

After creating an account at emoncms  we set about sending them some data. This is described here and the Perl script we used to connect to Xively has been altered to post to emoncms with JSON type data as described on their API input page. It looks like this:

http://emoncms.org/input/post.json?json={power:200}&apikey=xxxxxxxxxxxxxxxxx

Power is in Watts, but you can pass anything to them in this way, including multiple inputs like {power1:123,power2:456}. For graphing with Xively we separately sent current and (calculated) power, but with emoncms there is no point because any ‘visualisation’ – graph / readout / dial – can be scaled and so if we send power consumption, we can back-calculate to current. This means we are not doubling up the collected data.

Once we started posting data to our account, the feed was listed in the feeds page:

emoncms feeds

..where we could tell it to log the data, and then we could get a graph of the data from the visualisations page:

emoncms graph

 

Better still, we could make a dashboard:

emoncms dashboard

Dashboards can be made public and so you can publish them if you want (as can individual feeds). Great stuff!

Perl script for eco-eye serial to emoncms is here on Github.

 

Eco-Eye energy monitor serial data collection

A few years ago my minions installed an Eco-Eye energy monitor in the Labs. We bought it with a serial cable and it has been connected to a Mac Mini to collect data and push it to Cosm (now Xively) via a Perl script. The serial output is 19,200 baud, 8-none-1.Eco-Eye

The supplied serial cable uses a Prolific PL2303 USB to serial chip and so the Mac needs a driver installing which you can get from Prolific here. The current version creates a device named /dev/tty.usbserial (which is much better than the previous cryptic name).

The Eco-Eye data is simple – two bytes which make up the reading are sent every four seconds consisting of msb then lsb representing amps times 100. So, the reading in amps to two decimal places is:

amps = ((byte1 x 256) + byte2) / 100

There is a Perl module to handle posting to Xively called Net::Parchube (because Xively was Cosm was Parchube) which makes that part simple. The hardest part is keeping the bytes in sync – when you start the script you don’t know which one you get first, and sometimes one doesn’t turn up. To handle this, the script has a timeout which makes sure dud readings don’t make it through and corrupt your data. It also averages over seven samples to post a reading about every 30 seconds.

Output will look something like this:

sample: 1, msb: 11, lsb; 18, amps: 28.34
sample: 2, msb: 11, lsb; 36, amps: 28.52
sample: 3, msb: 10, lsb; 244, amps: 28.04
sample: 4, msb: 11, lsb; 24, amps: 28.4
sample: 5, msb: 11, lsb; 28, amps: 28.44
sample: 6, msb: 11, lsb; 8, amps: 28.24
sample: 7, msb: 10, lsb; 240, amps: 28
2014-08-12 10:15:18 avg_amps: 28.28

And on Xively:

xively_data

As you can see, the script also sends a power figure calculated from the amps.

The script runs in the foreground which is not ideal, but it does the job. You can get it from Github here: https://github.com/cllarky/perl-sensor-net/blob/master/eco-eye/serial-cosm.pl