Monday, September 7, 2020

GPS Module

An MQTT GPS module, what good could that be in a home automation system? The home isn't moving, of course. GPS tells us where something is right? That isn't how GPS works.

GPS satellites just broadcast the time, and where the other satellites are, and that is it. The GPS receiver calculates the difference in time signals that it receives from the various satellites in view. The GPS receiver can determine a very accurate time for where it is at, along with the altitude, course, speed and position. 

Now the house isn't moving, so the course and speed will be somewhat irrelevant. The altitude can be used to correct a barometer. The time is very useful. 



Many simple inexpensive GPS receivers are available I chose the ublox 7m receiver that I had left over from a quad copter. This module has the antenna built in, along with a compass that I am not using. It is about the same size as the Wemos D1 modules. I stacked them using LED leads. to connect the two data lines to the D1. I needed to cross the power and ground, since those pins are fixed, and matter what order. The data pins can be specified in software. 



Writing another MQTT module was pretty simple. 

I have a JSON message that looks like:

{
  "sensor": "gps",
  "time": [
    2020,
    9,
    7,
    23,
    59,
    57,
    0
  ],
  "Latitude": 44.83777,
  "Longitude": -93.46817,
  "Satellites": 10,
  "HDOP": 84,
  "Altitude": 284.4,
  "Course": 331.19,
  "Speed": 0.38892
}

The time fields are year, month, date, hour, minute, second and milliseconds. This format allows using any parts that are desirable. 

Node red supports a map node. The example map node displays flights from flight radar 24

Here is the code:

/*     
 * The code is copyright 2018, Tom Brusehaver 
 * It can be copied using the OSF v3 license. Do what you want with this, but share.
 * 
 * This uses a ublox 7m GPS device at 9600-baud serial hooked up on pins 2(rx) and 0(tx).
 *
 * The board selected in the IDE is WeMos D1 R2 & Mini. Standard everything 
 * 
 */
 
#include <SoftwareSerial.h>

#include <TinyGPS.h>

#include <ESP8266WiFi.h>m
#include <PubSubClient.h>
#include <PubSubClientTools.h>

#include <ArduinoJson.h>

TinyGPS gps;
SoftwareSerial ss(2, 0);

const char* ssid = "raspi-webgui";
const char* password = "xxxxxxxxx";
const char* MQTT_SERVER = "10.3.141.1";

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

WiFiClient espClient;
PubSubClient client(MQTT_SERVER, 1883, espClient);
PubSubClientTools mqtt(client);



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

  setup_wifi();
  String s = "";
    // Connect to MQTT
  Serial.print(s+"Connecting to MQTT: "+MQTT_SERVER+" ... ");
  if (client.connect("GPSClient")) {
    Serial.println("connected");
  } else {
    Serial.println(s+"failed, rc="+client.state());
  }
}


void setup_wifi() 
{
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//////////////////////////////////////////////////////////////////////////
//////////  MQTT Stuff ///////////////////////////////////////////////////

void reconnect()
{
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("GPSClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "GPS connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void publisher(char *gpsMSG) {
  StaticJsonDocument<300> doc;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  float flat, flon;
  //unsigned long age, date, time, chars = 0;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  
  doc["sensor"] = "gps";
  JsonArray time = doc.createNestedArray("time");
  time.add(year);
  time.add(month);
  time.add(day);
  time.add(hour);
  time.add(minute);
  time.add(second); 
  time.add(hundredths);

  gps.f_get_position(&flat, &flon, &age);
  doc["Latitude"] = flat;
  doc["Longitude"] = flon;
  doc["Satellites"] = gps.satellites();
  doc["HDOP"] = gps.hdop();
  doc["Altitude"] = gps.f_altitude();
  doc["Course"] = gps.f_course();
  doc["Speed"] = gps.f_speed_kmph();

  // Generate the minified JSON and send it to the Serial port.
  //
  //serializeJson(doc, Serial);
  // The above line prints

  // Start a new line
  Serial.println();
  char buffer[256];
  serializeJson(doc, buffer);
  mqtt.publish("gps/location", buffer);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  char gpsMsg[300];
  
  gps.stats(&chars, &sentences, &failed);

  publisher(gpsMsg);
  client.loop();
  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}


Saturday, August 15, 2020

It's Over (A New Tack).

I have given up on building a standalone engine monitor. Several reasons, but the biggest, I can buy basically the basis for $200. Once I started looking at part prices, and all, I decided to look at what is out there. I looked at Dynon, GRT and MGL. 

MGL has a remote data acquisition computer (RDAC) for 4 cylinder engines for about $200. The RDAC XG supports both CAN and RS-232 communication. The CAN bus is the most interesting, since that is how most modern cars talk to their instruments. The device can monitor 4 CHTs, 4 EGTs, Oil Pressure, Oil Temperature, Current, Volts, Tachometer, Fuel Flow, Coolant, and two aux inputs. 

MGL doesn't have the best reputation, but I am sure it is quite reliable compared to anything I can put together, and will be considerably cheaper than the prototype. This unit seems to be the quite capable for what I want. I could still use the phone or tablet as a display. The CAN or RS-232 bus could be converted to USB, Bluetooth, or WiFi. 

There you go. Why would I build something when I could buy it for less. 


So what is my plan? 

Modules! Well, node-red or MQTT modules that can be put anywhere, airplane, tractor, scooter, etc. The RaspberryPI as the hub can allow all kinds of configurations, displays, inputs. These modules can be temperature sensors, pressure sensors, GPSs, IMUs, etc. 

Saturday, August 8, 2020

Part Prices

I was looking at laying out a prototype board, something better than the proto board I am using now. I really like the MAX6675 for the thermocouples. The protoboard is looking good with 4 of the Arduino modules on there. I've built some braces for the modules, and it should be good for ground testing. 



I can buy the Arduino modules with the cap from the data sheet, 0.1" pins and a screw terminal for about $4.00 all day long. If I want to buy the bare chip, it is $9.00-$11.00! Why? I thought the Arduino modules might be using a clone chip, but when I magnify the chip, it clearly says MAX6675ISA. Is it counterfeit? I would thing MAXIM, or whoever would be catching these at customs if that were true. I just don't get it. 

I need to do some more research. Find out if there is some magic I am missing. I am sure I could request samples, and probably get what I need for very little, but if someone were to want to reproduce my work, well, it could get very expensive. 

I know I said I ordered 3 meter thermocouples, I was wrong. I ordered 2 meter cables, and boy are they long! I could have gotten away with meter and a half cables for the two front (rear) cylinders, and 1 meter for the back cylinders. Anyway, they aren't built well, so I may need to modify them anyway. The crimp joints don't have any strain relief, and that is where things are likely to break. I 3D printed a brace to support the modules.


The code has been modified for talking to all 4 modules. I think I'll only have 4 on this board, due to space. Eventually I'd like to use 4 more of the same module for the EGT temperature measuring. I am also using the Hall Effect Linear Current Sensor Module ACS712 for Arduino for measuring current to the panel. I haven't the software for that yet. 

I am printing a proto mount for the firewall now. I use tinkercad for these parts. The links are here, if you want to use them. Let me know if you do. 


ProtoMount                       ModuleBrace




      

Tuesday, July 28, 2020

Trying Things Out on An Airplane.

I finally did it. I have an ESP32 talking to a thermocouple connected to a Lycoming O-360!

I am using bayonet K type thermocouples, on the CHT ports built into the cylinder heads of the engine. They are in a 3/8-24 hole that is about 2 inches deep on the bottom of the cylinder near the bottom spark plug.

This is cylinder 1 near the prop. The bayonet adapter is the shiny metal part, just below the sparkplug. The tube on the left is the intake for the cylinder.

The temperature measurement is working, and seems pretty accurate. For now it is only reading one thermocouple, since that is all I have. I am using the MAX6675 Arduino module available from all the usual outlets for about $5 each. I have 4, but one isn't like the others, and doesn't seem to work. I'll have to order a couple more.

I only have one of these thermocouples, but I have 4 on order. The thermocouple I have only has about and 18inch wire coming out of it. The thermocouples I have on order have 3 meter wires, and should be more suitable for mounting the control box on the firewall.

The ESP32 controller I have now was hanging down between the USB cord and the thermocouple wire. It isn't suitable for use during the engine run. I ran the engine for about 3-4 minutes to get it up to about 200degrees F. I do have 2 sparkplug ring type thermocouples connected to an analog gauge that I can use while the engine is running. I can only read one CHT and EGT at a time, using a rotary switch.

After shutting down the engine, and ensuring all switches were off, I connected the esp32 to a laptop, and the thermocouple to the bayonet adapter. Then I used the Arduino serial monitor to read the output of the serialthermocouple example program that is available with the Adafruit MAX6675 library. The only changes I needed to make to the example program was tell it what pins the three SPI wires connect to.

A screen shot of the Arduino Monitor compares well with the analog gauge:

About 180-190 degrees F showing, while looking at cylinder 4 the opposite of cylinder 1 where the ESP32/MAX6675 was connected. (A Lycoming O-360 is a 4 cylinder boxer type engine, with cylinders 1 and 3 on onside of the engine and cylinders 2 and 4 on the other side of the engine).

The breadboad has expansion capabilities for up to 4 of these MAX6675 modules, a couple voltage dividers allowing the Oil and Fuel pressure analog sensor readings. The ESP32 WROOM module has capabilities for multiple SPI devices, all the analog readings that I may want, and more. It can do bluetooth, or WiFi.

As I work on this, I will add connectors for the additional modules. The USB connector is used for power and data transfer now. When I mount this in the airplane, I will supply power to the 5V input pin, and only use the USB connector for programming.

One thing I learned, the breadboard I bought was a terrible choice. There are a set of buses running the full length of the board. I need to cut traces like crazy. I forgot to cut the traced in the middle of the ESP32, and when I first powered it up, I could smell something. I hadn't soldered each pin in the socket, so I am sure that saved me, but a few power and ground pins ran into each other or other pins.



The scratches in the middle of the socket are where I needed to break the traces. I have to isolate the pads for the MAX6675 adapters since they are arranged longitudinally.

I've added the capability to display the temperature output via Bluetooth. The code is 90% the example code modified to output Bluetooth.


// this example is public domain. enjoy!
// https://learn.adafruit.com/thermocouple/
//
// Modified to output Bluetooth

#include "max6675.h"
#include "BluetoothSerial.h"

int thermoDO = 12;
int thermoCS = 14;
int thermoCLK = 27;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

float tempC, tempF, tempK;
char *titleTemp; 

BluetoothSerial  SerialBT;

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

  SerialBT.begin("ESP32_EngMon");    // Pair to this device

  Serial.println("MAX6675 test");
  // wait for MAX chip to stabilize
  delay(500);
}

void loop() {
  // basic readout test, just print the current temp
  
   tempC = thermocouple.readCelsius();
   tempF = thermocouple.readFahrenheit(); 
   Serial.print("C = ");
   SerialBT.print("C = ");
   Serial.println(tempC);
   SerialBT.println(tempC);
   Serial.print("F = ");
   SerialBT.print("F = ");
   Serial.println(tempF);
   SerialBT.println(tempF);
   
   // For the MAX6675 to update, you must delay AT LEAST 250ms between reads!
   delay(1000);
}


The output can be displayed on an Android device using the Bluetooth Terminal application available from the playstore.


Until next time...


Tuesday, March 24, 2020

MQTT and NodeRed on an airplane?

I've had several posts about using NodeRed for home automation, communicating with various nodes over MQTT. Could I do the same in the airplane? I think I could, and there would be some benefits to it. Certainly less wiring, and maybe more reliable and customizable.


The whole point of this blog originally was to use an Arduino and be able to monitor the engine status. Originally, I was going to use a Mega, and a bunch of shields. The old eco-system caused me to lean that way. Mega on the bottom, a custom shield next, and a Bluetooth shield on top. The world has moved on, and now I can use ESP-32 and 8266's with built in Wifi and Bluetooth. The boards only cost about $10, instead of the $20+ for the Mega and Bluetooth shield.

The sensors can mostly be wired to the ESP-8266 board with SPI (3 wire) communications, through adapter boards. If I need an analog or digital input, it is available on the board as well. There are very inexpensive thermocouple modules available, that would take care of the CHT and EGT measurements. The oil pressure and temperature would be analog inputs if I stick with the stock probes, but there is the Dallas18b20 probe that could be used to measure temperature, but there only one temperature measuring point on the engine. The Dallas 18B20 can be used for OAT measuring.

The oil pressure transducer is off on a flex pipe, with a manifold for to hold the hobbs switch. (theoretically, the oil pressure measurement could be combined in the computer somewhere to enable the hobbs timing measurements). There are nice solid state pressure sensors that may be appropriate for fuel and oil pressure, I need to do additional research.

Volt and Amp measurements can be done using the analog inputs, using the existing shunt for current measurements, or adding another shunt. There are also hall effect sensors that could be used to measure current. Using various current sensors would allow measuring all the important values at once, charge rate, drain rate, etc.

The tach measurement can come off the mag or EI unit. A transistor or optoisolator should work when connected to a pin that accepts interrupts.

Other sensors could be added or deleted anytime using additional nodes. If I want to measure the airflow through the baffles, I could add a node with multiple pitot tubes to see where the air might be leaking.

Then the question becomes, how many nodes should I use? It would be tempting to build one for each sensor, I want to limit the nodes to one function (I've said that before). How gray to I want that idea, one function could be all the thermocouples. Another node for all the oil information (pressure, temperature). Another for the fuel pressure, levels. Convenience may dictate some other arrangement, like thermocouples left side, thermocouples right side, that way the wires don't have to be so long.

Each node will still need 5V or 3V connected. It would be tempting to use the micro-USB connectors on the boards to feed the power. I think, the constant vibration would make the connectors fatigue very quickly, and the power would be falling out. It would probably be best to solder the power to the boards.

A $10 raspberry PI zero could be the NodeRed/MQTT hub. The raspberryPI should be mounted inside the cockpit. I am sure the WiFi signal can get around the firewall on a plastic airplane. Even a metal aircraft should have WiFi from the engine compartment to the cockpit. I'd have to try it out though.

In the cockpit, PLA printed enclosures should work fine. In the engine compartment, there may be problems with PLA or printed enclosures (constant vibration, heat, and rain). 3D printing my own enclosures may be compromised quickly. It may take some experimenting, certainly to make appropriate mounting choices, considering the sensor wiring stresses and heat.

NodeRed should allow nice cockpit displays of the instruments, and allow logging in various formats including CSV. Using the same CSV layout as the COTS instruments (like J.P Instruments) would allow people to analyze engine performance using off the shelf tools (excel, etc). The file could be scp'd from the Arduino, right to a tablet or phone, taken home and analyzed.

I don't know. I see a few worrying things, but nothing that is really scary about doing it. Can you talk me out of it?








Sunday, March 8, 2020

Eggbot; filling in some missing information

I guess it is that time of year, people are building Eggbots. I built one, and needed to learn a bunch. Some of the information was vague, or not connected to the original design, or anyone elses design.



I started with a Russian frame that I liked on Thingiverse. This was mostly lacking any real documentation. Elliot from Hackaday has a page with lots of information, including how to make a CNC shield move a servo, and how to get G code out of inkscape.

The Russian frame had a bunch of options for the pen holder. I chose the simple one, and am having success using that with a sharpie fine point. Being an American, it was easier to get 1/4-20 5/16-18 threaded rod than 6mm, so that is what I used. I cut 3 1ft pieces. For the rest of the bolts and screws, I used metric (m4 and m3 mostly), since the motors assume metric.

One tool that I will call essential is the taper cutter. Cutting threaded rod is easy, but the threads are suddenly all mucked up. Either the taper goes away, and threading on a nut has to be aligned perfectly, or the threads are bunged up so badly nothing will thread on anymore. This tool will make the trouble disappear, in about 2 seconds!. Sure you could file a taper in using a file, or grinder, but for less than $5, why?

The Russian  frame also assumed some 16mm bearings, that I didn't order. Another similar frame used skateboard bearings in a holder with the same bolt pattern as the stepper motors. I just reprinted the left frame from the Russian frame and two of these bearing holders for the end.

I couldn't find O rings that would hang onto the egg good. One end or the other would slip, and the drawing wasn't real good. I found some #17 bath diverter washers that seemed to be a better shape, and fit the end caps well. They still slipped.


I've started playing with some table foot rubber pieces, like on the bottom of a crutch. They are more grippy. I'll update when I know more.

Some page, maybe another one on Thingiverse suggested I use a CNC V4 Shield. A great design, with the Arduino Nano right on the board with the stepper drivers. The trouble is, the common Chinese clone makers messed up the board. A couple others have figured out the changes needed, and published the wiring changes to make this board work.

What I have seen though, the inkscape G code output doesn't quite make the pen up/down command that the GRBL expects. The delays are about 100 times longer than they say (seconds instead of milliseconds) as well  (Update, in the save dialog, it lets you set delay to 0, that seems to work). Long delays with the pen over at an angle almost always messes up the continuation of the lines. I end up hand editing the G code output. I should probably build a python or perl script to fix the output, or just figure out what unicorn changes are needed.

Changing the GRBL source code, it is important to remember you moved the code to the Arduino directory, so change it there, not where you expanded the code. If the motors are going backwards, reverse the plugs on the CNC V4 board.

For test eggs, I have been using the 18 for a dollar plastic eggs that I can get at the Dollar Tree. I like hard boiled eggs, but I didn't think I'd eat 24-36 in the next couple of weeks. I should look into dry erase markers to see if I can erase the test eggs.