image

X10 Control Using Arduino, Modbus, and ScadaBR

X10 Lighting and appliance modules are cheap on Ebay, I wanted to control them with my HMI (ScadaBR) so I put a X10 and Modbus library together in an  Arduino to turn on and off the modules.

CM17A

imageThe Arduino can control the X10 Firecracker CM17A using a library found on the Arduino website.  http://playground.arduino.cc/X10/CM17A

The library comes with a cool demo sketch that will loop through and turn on and off an X10 module.

Modbus

imageI merged the CM17A code with my favorite Arduino modbus library so that I could simply write to coils in the Arduino to command X10 modules. https://code.google.com/p/arduino-modbus-slave/

It was then a snap to set up ScadaBR to command the modules on and off with any device with a web browser such as my windows phone.

VIdeo

 

Links

X10 library

http://playground.arduino.cc/X10/CM17A

Modbus Library

https://code.google.com/p/arduino-modbus-slave/

ScadaBR

http://www.scadabr.com.br/

Direct download for the modbus library with regular modbus and X10Modbus sketches as well as the X10 Firecracker library. Download and install both libraries.

Modbus Library

X10Firecracker

Relevant Blog Posts

Arduino Modbus PLC/RTU

http://www.electronhacks.com/2014/04/arduino-modbus-plc-rtu/

Home Automation HMI with Mango M2M

http://www.electronhacks.com/2014/04/afordable-arduino-modbus-plc-or-rtu/

image

How To Scale A Thermistor for An Arduino

Thermistors And Your Microcontroller

A thermistor is a simple temperature component, basically it is a variable resistor that the resistance changes in it depending on the temperature. Such a simple device needs a few more components and scaling in the microcontroller to give the desired C or F temperature reading.

Voltage divider

imageFirst you will need to build a voltage divider to convert the thermistors varying resistance to a varying voltage source to feed the analog input of the microcontroller. The voltage source and resister values can vary, all you want is to not pull too much current (use high value resistors) and provide a wide voltage range for the microcontroller for best accuracy.

Scaling

The microcontroller will receive a raw value that will need to be scaled.

The zero and span of the raw value will vary depending on the voltage range of the analog input on your microcontroller. My Arduino analog input is 0-5vdc, some Arduinos are 0-3.3vdc, Industrial equipment is usually 1-5vdc 1-10VDC or 4-20ma.

The raw value inside the controller will vary depending on the resolution of the analog input, The Arduino Uno’s ADC (Analog to Digital Converter) is  is 10 bit so at 0vdc you will read 0 raw and at 5vdc you will read 1023 raw. Industrial ADCs often use 15 bit resolution so zero and span will be 0-32767. This raw number then must be scaled to what ever unit of measurement desired, in this case degrees Fahrenheit.

Scaling in the software usually requires Gain (multiplier) and Offset (add or subtract).

Gain

To figure out the gain we will use a proportion and cross multiply then divide the ratios. Example: We can run the temperature from 35-85 degrees using our hand for heat and ice in a bag, we check this with a thermometer. The raw values we see in the microcontroller are 417-565. We find the total range traveled by this equasion: 85-35=50 the range traveled of the raw value is: 565-417=148

Then lets use a proportion equation like this:  50/1 = 148/x to find x simply cross multiply and divide (1*148)/50=2.96. This is how much we will divide the raw number by.

Note: To be completely accurate with the definition of gain (multiplier) we would find the inverse so 1/2.96 = 0.33784 then multiply our raw number by it however I apologize, in my code example I just divided by 2.96, same result.  In the Arduino who cares but in some industrial applications they will expect an actual Gain(multiplier).

Offset

Offset is how much we need to move the value up or down. We will figure this on the lower values tested which was 35DegF-417raw. We will take into account that we will be dividing by 2.96 In this example equation: (417/2.96)-35=129.

Fine tuning

Since the methods I used to running up and down the temperature were quite primitive and not very accurate (bag of ice and my hand verified with cheap thermometers) I expected to have some fine tuning to do. After you get the scale close you can tweak the Gain and Offset to get the reading as close as possible. Also read the data sheet on your thermistor, most are not exactly linier so even with the perfect Gain and Offset there will be error.

Video

P.S. This scaling procedure works with just about any analog input, i.e temperature, pressure, voltage, humidity, etc..

The Arduino Sketch

int Ai0 = A0;
int Value0;

void setup() 
{
   Serial.begin(9600);
   Serial.println("www.Electronhacks.com");
}

void loop() 
{
    Value0 = analogRead(Ai0); //Read the value of AI1 (pin0) and write it to Value0
    Value0 = ((Value0/2.82)-108); //Scale the value 

    Serial.print("Raw-");
    Serial.print(analogRead(Ai0));
    Serial.print("  Scaled-");
    Serial.println(Value0); 
    delay(1000); 
}

Arduino Modbus PLC / RTU

PLC/RTU

A Programmable Logic Controller, PLC or Programmable Controller is a digital computer used for automation of electromechanical processes, such as control of machinery on factory assembly lines, amusement rides, or light fixtures. PLCs are used in many industries and machines.  http://en.wikipedia.org/wiki/Programmable_logic_controller

A remote terminal unit (RTU) is a microprocessor-controlled electronic device that interfaces objects in the physical world to a distributed control system or SCADA (supervisory control and data acquisition) system by transmitting telemetry data to a master system, and by using messages from the master supervisory system to control connected objects.[1] Another term that may be used for RTU is remote telemetry unit. http://en.wikipedia.org/wiki/Remote_Terminal_Unit

Arduino Modbus

This setup can turn your Arduino into a PLC or RTU like device that can communicate via the Modbus protocol.There are a lot of arduino modbus libraries out there however this is the one that I love, it just works. It can also be easily extended to include more internal bits or holding registers to return internal data, counters, scaled values, or WHATEVER YOU WANT!

Demonstration

How to build it!

 

Resources

Forum post on the Arduino website http://forum.arduino.cc/index.php?topic=150181.0

Where to get the library http://code.google.com/p/arduino-modbus-slave/downloads/detail?name=MODBUS.zip&can=2&q=

My blog post on building the accompanying Mango M2M HMI http://www.electronhacks.com/2014/04/afordable-arduino-modbus-plc-or-rtu/?utm_medium=facebook&utm_source=twitterfeed

Code

#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>

/* PINS
Add more registers if needed
Digital input pins 2,3,4,5,6,7
Digital output pins 8,9,12,13
Analog output pins 10,11 (PWM)
Analog input pins 0,1,2,3,4,5
*/


modbusDevice regBank;
modbusSlave slave;

int AI0,AI1,AI2,AI3,AI4,AI5;


void setup()
{   
  regBank.setId(10); ///Set Slave ID

//Add Digital Input registers
  regBank.add(10002);
  regBank.add(10003);
  regBank.add(10004);
  regBank.add(10005);
  regBank.add(10006);
  regBank.add(10007);
// Add Digital Output registers
  regBank.add(8);
  regBank.add(9);
  regBank.add(12);
  regBank.add(13);
//Analog input registers
  regBank.add(30001);
  regBank.add(30002);
  regBank.add(30003);
  regBank.add(30004);
  regBank.add(30005);
  regBank.add(30006);
//Analog Output registers
  regBank.add(40010);  
  regBank.add(40011);  

  slave._device = &regBank;  
  slave.setBaud(9600);   
  
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  pinMode(6,INPUT);
  pinMode(7,INPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(13,OUTPUT);
   
}
void loop(){

  while(1){   
  //Digital Input
    byte DI2 = digitalRead(2);
    if (DI2 >= 1)regBank.set(10002,1);
    if (DI2 <= 0)regBank.set(10002,0);
    byte DI3 = digitalRead(3);
    if (DI3 >= 1)regBank.set(10003,1);
    if (DI3 <= 0)regBank.set(10003,0);
    byte DI4 = digitalRead(4);
    if (DI4 >= 1)regBank.set(10004,1);
    if (DI4 <= 0)regBank.set(10004,0);
    byte DI5 = digitalRead(5);
    if (DI5 >= 1)regBank.set(10005,1);
    if (DI5 <= 0)regBank.set(10005,0);
    byte DI6 = digitalRead(6);
    if (DI6 >= 1)regBank.set(10006,1);
    if (DI6 <= 0)regBank.set(10006,0);
    byte DI7 = digitalRead(7);
    if (DI7 >= 1)regBank.set(10007,1);
    if (DI7 <= 0)regBank.set(10007,0);
                                
  //Digital output
    int DO8 = regBank.get(8);
      if (DO8 <= 0 && digitalRead(8) == HIGH)digitalWrite(8,LOW);
      if (DO8 >= 1 && digitalRead(8) == LOW)digitalWrite(8,HIGH);
    int DO9 = regBank.get(9);
      if (DO9 <= 0 && digitalRead(9) == HIGH)digitalWrite(9,LOW);
      if (DO9 >= 1 && digitalRead(9) == LOW)digitalWrite(9,HIGH);
    int DO12 = regBank.get(12);
      if (DO12 <= 0 && digitalRead(12) == HIGH)digitalWrite(12,LOW);
      if (DO12 >= 1 && digitalRead(12) == LOW)digitalWrite(12,HIGH);
    int DO13 = regBank.get(13);
      if (DO13 <= 0 && digitalRead(13) == HIGH)digitalWrite(13,LOW);
      if (DO13 >= 1 && digitalRead(13) == LOW)digitalWrite(13,HIGH);
            
  //Analog input  ***READ Twice deliberately
    AI0 = analogRead(0);
    delay(10);
    AI0 = analogRead(0);
    regBank.set(30001, (word) AI0);
    delay(10);
    
    AI1 = analogRead(1);
    delay(10);
    AI1 = analogRead(1);
    regBank.set(30002, (word) AI1);
    delay(10);
    
    AI2 = analogRead(2);
    delay(10);
    AI2 = analogRead(2);
    regBank.set(30003, (word) AI2);
    delay(10);
    
    AI3 = analogRead(3);
    delay(10);
    AI3 = analogRead(3);
    regBank.set(30004, (word) AI3);
    delay(10);
    
    AI4 = analogRead(4);
    delay(10);
    AI4 = analogRead(4);
    regBank.set(30005, (word) AI4);
    delay(10);
    
    AI5 = analogRead(5);
    delay(10);
    AI5 = analogRead(5);
    regBank.set(30006, (word) AI5);
    delay(10);
        
  //Analog output 
    word AO10 = regBank.get(40010);
    analogWrite(10,AO10);
    delay(10);
    word AO11 = regBank.get(40011);
    analogWrite(11,AO11);
    delay(10);
        
  slave.run();  
  }
}

Home Automation HMI with Mango M2M

HMI

A HMI (Human Machine Interface) is the system by which people can interact with a machine. The user interface includes hardware (physical) and software (logical) components. User interfaces exist for various systems, and provide a means of:

  • Input, allowing the users to manipulate a system
  • Output, allowing the system to indicate the effects of the users’ manipulation

http://en.wikipedia.org/wiki/Human_machine_interface

 

Mango M2M and Arduino

In this case we are using an Arduino for the microcontroller which Mango  can communicate with using the Modbus Protocol. Mango M2M is no longer in development however you can still get it for FREE. I suggest getting version 1.12.1 as 1.12.5(latest) had a bug where it was throwing an error every time you load a page. There are a few mango clones out there that are activelyactivly being developed which I intend to try out eventually.

Infinite Automation took over Mango M2M a few years ago, they offer a free version with limitations http://infiniteautomation.com/

ScadaBR is a derivative of Mango and free as far as I know however the company is German, I am not sure how good the English support is. http://www.scadabr.com.br/

The bottom line is Mango M2M has some great features and for the price of free it is hard to beat. I am a little disappointed in the flexibility when it comes to screen creation.

Installing Mango M2M

How to build the HMI

Resources

The old Mango site where you can get your hands on the software. http://forum.infiniteautomation.com/download.jsp

Java SE 6 Download http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html#jdk-6u45-oth-JPR

My Blog Post on the Arduino Modbus PLC/RTU http://www.electronhacks.com/2014/04/arduino-modbus-plc-rtu/

I can’t find Mango 1.12.1 online anywhere so here is a direct download of the windows version. http://www.electronhacks.com/eh/Files/Mango/mango-1.12.1.zip

Installation instructions

Prerequisites
Java JDK

Mango requires the pre-installation of Java JDK 1.6.

RXTXcomm

Serial-based data sources (such as Modbus RTU) require the presence of the RXTXcomm API software. If you do not use these protocols, you can skip this section.

Download the following files to the given directories. RXTXcomm.jar is required for all host types. Note that the Linux library is for x86 hosts only. For other host types, please see rxtx.org.

•RXTXcomm.jar: save in <jdk1.6-home>\jre\lib\ext

•rxtxSerial.dll: save in <jdk1.6-home>\jre\bin

•librxtxSerial.so: save in <jdk1.6-home>/jre/lib/i386

Apache Tomcat

Mango is a web application that requires a Java Servlet/JSP container within which to run. It has been tested with Apache Tomcat, but has no known dependencies. If you already have Tomcat or another container installed, you should be able to install the Mango WAR file as a web application. If you do not have a container installed on your host system, you can download Tomcat.

Mango M2M Binaries

If you only wish to run Mango as an application, download the binary package for your system. mango-1.12.5.zip

mango-1.12.5.tar.gz

Mango M2M Source

Mango source is available for version 1.12.5. More recent source code will be available in the upcoming release of Mango Automation.

Installation instructions

These instructions assume that you have successfully installed the Java JDK 1.6.0 (or higher), and RXTXcomm if required).

Ensure that JDK 1.6.0 runs by default by executing the command “java -version” at a command prompt. (It should print out “java version “1.6.0″”.) Mango will not start properly under an older version of Java. If the correct version of Java is not displayed, set your JAVA_HOME environment variable to <jdk1.6-home>.

Create a directory in which to unzip Tomcat. We will refer to this directory as <tomcat-home>. Unzip Tomcat in this directory. By default, Tomcat will service requests at port 8080. To change this to another port, edit the “Connector” element in <tomcat-home>/conf/server.xml.

To start Tomcat, execute either <tomcat-home>/bin/startup.bat (Windows) or <tomcat-home>/bin/startup.sh (*nix), depending on your host system type. If Tomcat started successfully, you should see a Tomcat welcome page when you direct your browser to http://localhost:8080/ (if you did not change the port in server.xml).

Shut down Tomcat before continuing with the installation. Either close the Tomcat window, or execute either <tomcat-home>/bin/shutdown.bat (Windows) or <tomcat-home>/bin/shutdown.sh (*nix), depending on your host system type.

Installing Mango M2M

These instructions assume that you will be installing Mango as the root application within Tomcat.

You may optionally clear out the applications that are shipped with Tomcat, as they are not required. To do so, delete all directories under <tomcat-home>/webapps. Then, recreate the ROOT subdirectory.

Unzip the Mango binary archive into the <tomcat-home>/webapps/ROOT directory. When you start Tomcat next (see above), Mango will be started as well. Depending on the speed of your system it could take a few minutes to create the database tables. Tomcat (and Mango) will have completed starting up when the Tomcat console displays the message “INFO: Server startup in xxx ms” (where “xxx” is the number of milliseconds it took to start up). When you direct your browser to your Tomcat installation, you should now see the Mango login page.

Upon installation, Mango creates a single login account with username “admin” and password “admin”. Once you log in, you are strongly encouraged to change at least the password for this account on the “Users” page (). Also, you can set various system properties on the “System settings” page ().

image

Kossel Mini 3D Printer Accessories and Modifications

Heimagere are some 3D printer accessories and modifications I couldn’t live without.

1. Hot end cooling fan.
2. Hot end cooling fan shroud.
3. Bead cooling fan.
4. Bead cooling fan bracket.
5. Remove D1 so that the  Arduino does not receive harmonic distortion from the stepper motors and heating loads.
6. Electronics Enclosure.
7. Electronics Cooling.
8. Bed Lighting.
9. Lighting and fan control.
10. Power Switch.
11. Stepper motor wiring harnesses.
12. Stepper motor wire bracket.
13. Aluminum print surface.
14. Heated print bed.
15. Filament Spool Holder.
16. Extruder and adjustment.
17. Cheaper rail system.

Most things can be downloaded here: http://www.thingiverse.com/electronhacks/designs

image

RAMPS 3D Printer Electronics Enclosure

imageWhen you build your own 3D printer you can put the electronics just about anywhere.  I chose a RAMPS 1.4 enclosure off of Thingiverse and then modified the sides to my liking.

I then added a 50mm cooling fan, power indicator and switch,  and knobs and switches to control lighting and three fans.

You can download the STL files here: http://www.thingiverse.com/thing:258797

image

Kossel Mini 3D Printer Heated Aluminum Print surface

imageI finally came to the point where I had to figure out a heated bead for my Kossel Mini 3D printer. It is OK to print smaller objects using PLA plastic without a heated bed however to print larger objects or use ABS you must have a heated bed to prevent warpage.

image
I also decided to try Aluminum after breaking my glass print surface and it is amazing! Aluminum heats up quicker, heats  more evenly, will never shatter, and is much cheaper than borosilicate glass. To heck with all the poo pooers making people afraid to try aluminum because it might not be as flat. I just grabbed a used aluminum backplane out of an electrical box and I can’t find any un-flatness whatsoever.

 

P.S. Another reason to keep your print warm is so that the layers adhere to each other properly. It can be an issue if on large prints the object cools to room temperature while printing. Sure it might look good but structurally the layers may be barely hanging on to each other.

image

3D Printer Hot End Review

It is a bit of a chore to research all the different types of hot ends and attempt to figure out which one to sink your cash into. I have had over six different types of hot ends, by far the J-Heads have been the best. Usually the all metal or solid ceramic hot-ends conduct so much heat up the filament that it will jam easily. For my Kossel Mini I selected a J-Head clone from china on EBay hoping to save 30 bucks however it didn’t work out. It did melt the plastic however the feed rate was so slow that I had to slow down my printer drastically. I finally spend the money on a Mk V-BV from Reifsnyder Precision Works/ TriDPrinting.com/ Hotends.com. Now I can print at decent imagespeeds and am very happy so I figured I would give them an honest shout out.

 

There may be better hot-ends out there and I hope that someone will put out a definitive hot-end buyers guide someday. For now we will have to wade through the disorganized community and try to decipher which way to go.  A lot of information on the web seems to be either one sided, misguided, or have so little info or comparison that it makes it hard to make choices. Sorry if this sounds like a rant but my pocketbook found out the hard way that all hot-ends are not made equal.

image

Greg’s Accessible Extruder Assembly for Kossel Mini

I started out with Airtripper’s direct drive extruder on my 3D printer and while I liked it a lot I found out that normal stepper motors will not work. You need a hefty stepper motor and even at that I doubt the ramps stepper drivers can handle it. It is suggested to use a gear reduced stepper with something like a 4:1 step down, these are fairly expensive so I opted to build a Greg’s extruder which has the approximant 4:1 step down that I needed.

image