Eliminate OEMGateway Buffer (Direct From Socket Listening)

I have a project where I'm looking to read from RTD's and display and track live data. It seems to be taking a lot of readings but not transferring them to Emoncms very quickly as I think they are stacking up in the buffer. I thought about turning down the sample rates but I really want to pull data and display every second instead of 10s if possible. I didn't know exactly how the listeners work and if I could just put the runtime_settings right into the listener and have it pass the data directly. Does anyone have any ideas on how to go about this?

Also when I use OEMGateway to pass data to Emoncms it seems to make 20-30 inputs that are inactive but I only have two being sent which it shows them as active. Don't know if anyone has any thoughts on that.

pb66's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Can you attach your code or explain a little more about what you have ?

OEMG forwards what it receives quite reliably, normally. It will only buffer what it can't deliver, although if you have a target that is not accepting or acknowledging, OEMG can get bogged down trying in vain to deliver. If you can turn on logging and post some logs it may show something.

Generally if OEMG gets good data frames and the targets are accepting and acknowledging then you are unlikely to experience any trouble with it, so I would confirm the data frames and targets are doing their bit before altering OEMG if you want it to do something custom that's different but it shouldn't need fixing to just forward data supplied via a socket.

Paul

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

/***************************************************************************
* File Name: serial_MAX31865.h
* Processor/Platform: Arduino Uno R3 (tested)
* Development Environment: Arduino 1.0.5
*
* Designed for use with with Playing With Fusion MAX31865 Resistance
* Temperature Device (RTD) breakout board: SEN-30201 (PT100 or PT1000)
*   ---> http://playingwithfusion.com/productview.php?pdid=25
*   ---> http://playingwithfusion.com/productview.php?pdid=26
*
* Copyright © 2014 Playing With Fusion, Inc.
* SOFTWARE LICENSE AGREEMENT: This code is released under the MIT License.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* **************************************************************************
* REVISION HISTORY:
* Author   Date  Comments
* J. Steinlage   2014Jan25 Original version
*
* Playing With Fusion, Inc. invests time and resources developing open-source
* code. Please support Playing With Fusion and continued open-source
* development by buying products from Playing With Fusion!
*
* **************************************************************************
* ADDITIONAL NOTES:
* This file configures then runs a program on an Arduino Uno to read a
* MAX31865 RTD-to-digital converter breakout board and print results to
* a serial port. Communication is via SPI built-in library.
*    - Configure Arduino Uno
*    - Configure and read resistances and statuses from MAX31865 IC
*      - Write config registers (MAX31865 starts up in a low-power state)
*      - RTD resistance register
*      - High and low status thresholds
*      - Fault statuses
*    - Write formatted information to serial port
*  Circuit:
*    Arduino Uno   -->  SEN-30201
*    CS: pin 10    -->  CS
*    MOSI: pin 11  -->  SDI (must not be changed for hardware SPI)
*    MISO: pin 12  -->  SDO (must not be changed for hardware SPI)
*    SCK: pin 13   -->  SCLK (must not be changed for hardware SPI)
*    GND           -->  GND
*    5V            -->  Vin (supply with same voltage as Arduino I/O, 5V)
***************************************************************************/

// the sensor communicates using SPI, so include the hardware SPI library:
#include <SPI.h>
// include Playing With Fusion MAX31865 libraries
#include <PlayingWithFusion_MAX31865.h>              // core library
#include <PlayingWithFusion_MAX31865_STRUCT.h>       // struct library

//Sensor addresses:
const byte CONFIG_REG_W = 0x80; // Config register write addr
const byte CONFIG_VALUE = 0xC3; // Config register value (Vbias+Auto+FaultClear+50Hz, see pg 12 of datasheet)
const byte ADC_WORD_MSB = 0x01; // Addr of first byte of data (start reading at RTD MSB)
const byte ADC_FAULT_REG = 0x07; // Addr of the fault reg

// CS pin used for the connection with the sensor
// other connections are controlled by the SPI library)
const int CS_PIN = 10;
const int nodeID = 10;

PWFusion_MAX31865_RTD rtd_ch0(CS_PIN);

void setup() {
  Serial.begin(9600);

  // setup for the the SPI library:
  SPI.begin();                        // begin SPI
  SPI.setDataMode(SPI_MODE3);         // MAX31865 is a Mode 3 device
 
  // initalize the chip select pin
  pinMode(CS_PIN, OUTPUT);
  rtd_ch0.MAX31865_config();
 
  // give the sensor time to set up
  delay(100);
}

void loop()
{
  delay(150);                                   // 500ms delay... can be much faster
 

  static struct var_max31865 RTD_CH0;
  double tmp;
 
  RTD_CH0.RTD_type = 1;                         // un-comment for PT100 RTD
  // RTD_CH0.RTD_type = 2;                        // un-comment for PT1000 RTD
 
  struct var_max31865 *rtd_ptr;
  rtd_ptr = &RTD_CH0;
 
  rtd_ch0.MAX31865_full_read(rtd_ptr);          // Update MAX31855 readings
 
  // Print information to serial port

  if(0 == RTD_CH0.status)                       // no fault, print info to serial port
  {
    if(1 == RTD_CH0.RTD_type)                   // handle values for PT100
    {
      // calculate RTD resistance
      tmp = (double)RTD_CH0.rtd_res_raw * 400 / 32768;
      Serial.print("nodeID");                            // print Node set to 10
      Serial.print(" ");
      Serial.print(tmp)
    }
    // calculate RTD temperature (simple calc, +/- 2 deg C from -100C to 100C)
    // more accurate curve can be used outside that range
    tmp = (((double)RTD_CH0.rtd_res_raw / 32) - 256) * 9 / 5 + 32;
    Serial.println(tmp);                          // print RTD resistance
  }  // end of no-fault handling
  else
  {
    Serial.print("RTD Fault, register: ");
    Serial.print(RTD_CH0.status);
    if(0x80 & RTD_CH0.status)
    {
      Serial.println("RTD High Threshold Met");  // RTD high threshold fault
    }
    else if(0x40 & RTD_CH0.status)
    {
      Serial.println("RTD Low Threshold Met");   // RTD low threshold fault
    }
    else if(0x20 & RTD_CH0.status)
    {
      Serial.println("REFin- > 0.85 x Vbias");   // REFin- > 0.85 x Vbias
    }
    else if(0x10 & RTD_CH0.status)
    {
      Serial.println("FORCE- open");             // REFin- < 0.85 x Vbias, FORCE- open
    }
    else if(0x08 & RTD_CH0.status)
    {
      Serial.println("FORCE- open");             // RTDin- < 0.85 x Vbias, FORCE- open
    }
    else if(0x04 & RTD_CH0.status)
    {
      Serial.println("Over/Under voltage fault");  // overvoltage/undervoltage fault
    }
    else
    {
      Serial.println("Unknown fault, check connection"); // print RTD temperature heading
    }
  }  // end of fault handling
}

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

What I have is not the norm I guess. I have a Raspberry Pi and a Arduino Uno and a playingwithfusion RTD to digital max adapter. I have that outputting into the serial out connected to the Pi with a usb cable. I'm using the OEMGateway to transfer that data using the serial listener. I had the program outputting the data every 100ms to the OEMGateway and that apparently is way too fast. But that's about the speed I want it to work at. 1 second intervals is about as slow as what I need it for can handle. I hope that's possible.

[[Socket]]
    type = OemGatewaySerialListener
    [[[init_settings]]]
        com_port = /dev/ttyACM0

 

pb66's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

10 times per second is fast, I can't imagine why you would want to report that frequently. I think you may have issues each step of the way using this method. Even if OEMG is able to maintain that speed, can the router, network and server accommodate ? and then if they did, what will the data do?

Where is the data being sent ? 

What is the incoming frame structure and value range ? can give examples?

Can the data be crunched locally and forwarded less frequently as totals or averages?

If you must have 10 samples per second. do they need to be forwarded at that rate could 100 frames be forwarded every 10 seconds? or 300 every 30 secs etc. OEMG could buffer and send in batches with a little modification.

I really do not know if OEMG can do that speed but I do know that it operates on one thread, so it may be worth looking at emonHub. although based on OEMG it has an additional thread for each target so if one is slow or not responding it will not slow the main loop.

Paul

 

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Yeah, unfortunately I know it's asking a lot. This setup is on a very fast network and everything is accessed locally. What I have is a group of motors that are hard to get to and kind of dangerous to get to for readings and such ( also getting someone to take a reading is like pulling teeth haha). What I am hoping for is to be able to get data quick enough to be able to save these motors. They can go in a matter of minutes and we do have people watching the data in the control rooms. What I have is an Arduino sending data to a PI through USB and the PI runs OEMG and hosts the EmonCMS server. It's all accessed over the local network. I'm working on a script to send an email and SMS alert to the techs when the motors start to get hot. The goal is to take readings for power, temp, humidity, and eventually vibration using the FFT libraries.

I haven't seen EmonHub. I'll have to check that out. I realize that I'm asking a lot of the software. I guess tolerable would be 1 reading per second. It could batch send if it had to. I just don't want there to be too much delay if possible. I really appreciate the help. I'm newer to the Emon stuff but find it fascinating. 

pb66's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

I'm not qualified or experienced in motor control but for what's worth I think you would be better to run some custom code locally, either a standalone intermediary program or modify either the output of the script above or the input of OEMG.

As it is currently I think the script above is outputting way too much for the OEMG input. not only is it fast but it's output is not guaranteed to be formatted correctly and so OEMG will need to also discard any unsuitable packets (additional workload) and at first glance it seems that warning messages will come at the times most critical to getting the data through.

If a warning is to be sent for the techs to action via email or text, a 3, 5 or even 10 second interval will have little impact on the techs response time, certainly a tenth of a second will have no noticeable effect to response times, but will probably have the system working at a rate that could delay messages or be prone to failure and leave you without protection.

This looks like a "less is more" scenario, the less you have going on and the less frequently you update, the more likely you are to get a timely and accurate warning.

Paul

Robert Wall's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Putting on my systems engineer's hat, it strikes me that your philosophy is totally wrong. It's a classic case of where the line between monitoring and protection has been crossed. Those are two functions that ought to be kept quite separate.

If a motor is getting hot, you shouldn't be expecting someone to come off their tea break to take remedial action. Your control system should be reducing the load or, if necessary, shutting the process down in a controlled fashion to prevent further damage. You should be using the data after the event to look for the cause of the motor getting hot, not relying on human intervention as a result of an SMS message.

I have no idea what your process is, but in my book and in general terms, what you need to be doing is:

1. The motor temperature starts to rise: You flag a warning to the control room operators.
2. If the temperature continues to rise, the control system should reduce the load or start an orderly shutdown.
3. If the temperature reaches the critical value where damage to the insulation is imminent, the control system should immediately stop the process (and if the control room operators ignore the warning in (1) or override the system in (2), it's for management to take disciplinary action).

[Or, as a supervisor at a brewery once said to me: "I like having you lot here - you're engineers. You shut the plant down safely first before any damage is done, then you worry about the software bug."]

But I have to ask, why is the motor getting hot? There can be 3 causes: overcurrent, harmonics in the supply or a ventilation failure. The standard motor protection should be capable of dealing with overcurrent if it's been specified properly at the design stage (and not been 'improved' later).

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

It's the fourth and most common reason we have around here; Lack of lubrication. I use to work for a motor shop for many years and we've seen some serious damage caused to shafts and housing from the bearings overheating. Around here it's like pulling teeth to get someone to lubricate especially on these particular motors. I know it a management problem but with unions here we don't seem to get anywhere.

Yes I agree that it crosses the line between monitoring and protection but we don't really have another way other than a retrofit which really isn't going to happen on our budget. I'm just doing this to make our lives a little easier. We have controls to monitor vibration that require a person to go out and trend the bearings on the motors but that doesn't happen very often and in the case of vibration we usually catch things early. But in the case of bearing thermal protection, we have none.

So I guess what I'm saying is that getting data in 10s intervals is fine and would work. I just was trying to come up with a way to get more real time data. Mostly I'm trying to be as proactive as possible and with the the code I have right now it seems to be stacking up tons of points in the buffer and then releasing them slowly. I'm just here for help if anyone has suggestions I openly welcome them.

pb66's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Initially you could leave OEMG pr emonhub as it is and concentrate on the sketch. You could have the sketch averaging and totaling etc and then every so many seconds send the data via serial in the normal way, ie an array of values in a predefined order that can be relayed to emoncms or elsewhere for monitoring and or analysis, with an alert mechanism actioned from that data. you could probably use the events module combined with something like https://www.notifymyandroid.com to alert the techs and once you have the procedure in place and working, you can maybe start increasing the frequency.

Maybe just not to the point where the raspberry pi needs overheat monitoring to prevent burnout :-)

Paul

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Okay I took your advice on the averaging. It works a lot better now. I brought it down to 5 sec and it isn't stacking up in the buffer anymore! I really appreciate the help. I got an email alert script up and running. Now the only thing I can't figure out is why I can't get emoncms to run as a daemon when the Pi starts up. 

pb66's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Good to hear you're making progress

Do you mean you can't get OEMG to run as a daemon ? emoncms doesn't need starting as such, normally the "server" starts when apache and mySQL start at boot up.

How are you currently starting it?

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Sorry, my brain has been elsewhere. I mean OEMGateway. I went through the instructions a few times looking for any possible mistakes but I can't find any. It's very frustrating. I hope I have time to do a write up on all this when I'm done.

pb66's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

From memory I think can vaguely recall having a similar issue many months ago, but I didn't pay much attention, as if I recall correctly it cleared when I carried out the additional steps to enable logging. So I would recommend doing that first and if still no joy then a little more info would help.

How are you currently starting OEMG?

Where is your conf file located?

Are you able to use the daemon start or stop commands at the command line?

sprocket_3's picture

Re: Eliminate OEMGateway Buffer (Direct From Socket Listening)

Well at long last my problems have all been solved and it's been up and running for almost 1 year. I ended up going with playingwithfusions pt100 to spi converter and used an arduino to convert and buffer the data to serial through the usb port. Then configured the Pi with emoncms and oemgateway and had it input the serial signal. The original pi couldn't handle the load of 4 sensors reading ones every 10 sec in 2 sec increments. But the Pi 2 loves it. Currently am adding CT's to the mix for power spike detection and will be adding vibration monitoring in the future. Right now we have this installed on our industrial bake oven to determine part temperature. Works great.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.