Categories
Arduino

ChatGPT and Arduino

Unless you’ve been hiding under a particularly large rock, you must have hear of OpenAI’s chatGPT: a publicly accessible Artificial Intelligence that is surprisingly helpful. How helpful? Well, it can even be used to write Arduino code!

And that’s where the problems begin. For an experienced programmer, chatGPT is amazingly useful: it can produce custom versions of commonly-needed code in seconds. However, for a beginner, or a non-programmer, the downsides may outweigh the benefits. One of the problems with chatGPT-generated Arduino code is that it can be wrong in subtle, or even obvious ways. To someone who writes code for a living (like yours truly), these bugs are easy to find. For a neophyte, it looks fine and it’s not until they try to run it that it fails in mysterious ways. And worst of all, as good as chatGPT is at writing code, it’s terrible at debugging it. So if your Arduino code that chatGPT generated doesn’t work, you’re pretty much out of luck.

I’ve been getting more and more email from people in this particular quandary. They’ve tried using chatGPT to write code for their desperately-needed Arduino system, but it doesn’t work and they can’t figure out why.

Well, that’s why this site is here: we can fix the problem and write professional grade code that you can rely on, and best of all, it works 🙂




If you'd like to subscribe to this blog, please click here.

Categories
Uncategorized

All about resistors

Resistors are one of the fundamental electronic components. They fall into the category of linear devices because their behavior is predictable by a linear equation. That is, the voltage across a resistor is a linear multiple of the current passing through it:

voltage (V) = Current (i) x Resistance (R)

Important resistor characteristics

The resistance, the amount that a resistor impedes or “resists” current flow, is measured in ohms. Commonly, the Greek letter omega Ω is used as an abbreviation. e.g., a 10,000 ohm resistor is shown as 10kΩ. The power rating of a resistor is measured in Watts (W). In many applications, the power rating is important because if it is exceeded, the resistor will become very hot and physically fail, possibly even bursting into flames. For most applications in Arduino-based circuits, power is not likely to be a significant issue.

What they look like

Resistors can take a lot of different physical shapes. Here are a few examples.

1.5ohm, 10Watt Power resistor

(By Emilian Robert Vicol from Com. Balanesti, Romania – Ceramic-Encapsulated-Resistor_23268-480×360, CC BY 2.0, https://commons.wikimedia.org/w/index.php?curid=38383544)

Various through-hole resistors

Surface-mount resistors

Electric kettle

Yes, an electric kettle is an example of a very high-power resistor. It uses the resistance of high-temperature wire to turn the electricity into heat.

What do we need them for?

The function of a resistor is to impede current flow. That’s it. That’s literally all they do. However, that simple statement means that they can be used for lots of different things.

Pullups/pulldowns the digital inputs to a microcontroller need to have a set HIGH or LOW state. This means that they must be fixed to the positive voltage supply (Vcc) or ground (GND). Leaving them to find their own voltage level can cause the state of the input to be constantly changing between HIGH and LOW as that floating voltage changes. A pullup or pulldown resistor is normally used if the device that is driving the input does not have a natural HIGH or LOW state. We would not want to connect the input directly to Vcc or ground, because in that case, if we were to connect the input to a signal that changes the inputs’s state, it would mean a short circuit between Vcc and ground, which is a serious problem.

One example of such a device would be a switch. Most modern processors include an internal circuit that allows the programmer to enable the input to be pulled up to Vcc, but still allows a switch or other device to drive the input to a LOW state. This is called an “internal pull up.” In many cases, an internal pull down can also be configured.

If the processor does not have built-in pull ups, or if a stronger pull up is needed (the internal ones are quite weak: on the equivalent of a 100k resistor), then an external resistor can be used in this case.

Current limiting This circuit uses a resistor to limit the current through a Light Emitting Diode (LED). Without the resistor, the LED would consume too much current and likely fail from overheating.

LED current limiter

A pair of resistors can reduce a voltage. In the diagram below, there are two resistors, R1 and R2. The zigzag is the standard schematic diagram symbol used to depict a resistor. Here an input voltage, Vin, is changed by the formula below to an output Vout. This circuit configuration is called a voltage divider because it divides the input voltage by a fixed amount.




If you'd like to subscribe to this blog, please click here.

Categories
Arduino

Program ESP32 without the Arduino IDE

I recently had to make a field upgrade to the software on some ESP32-based devices. I didn’t want to have to require that the operator go through the entire process of installing the Arduino IDE, download libraries, and all that not-so-fun stuff. For us techies, it’s no big deal. For a non-technical user who has tons of more important things to do, it becomes a royal pain in the butt.

So, what to do? From watching the IDE output, I could see that it called esptool.exe. A bit of research into this tool and it looked like the only problem we were likely to run into was figuring out which virtual COM port had been assigned to the device. Also, since there were a number of these units to reprogram, it needed to be efficient.

Enter the chgport command. chgport lets you change port settings, but for my purposes the most important part was that it lists the COM ports connected to the PC.

I could redirect the output from chgport to a file, then parse that file and supply esptool with the COM port of the device. After verifying this manually, I went forward and built this script.

set BOOT=PROGRAM.ino.bootloader.bin
set PART=PROGRAM.ino.partitions.bin  
set PROG=PROGRAM.ino.m5stack_core2.bin
set APP=boot_app0.bin

chgport > port.txt
set /p PORTLINE= < port.txt
set PORTNAME=%PORTLINE:~0,5%
echo %PORTNAME%

esptool.exe --chip esp32 --port %PORTNAME% --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 16MB 0x1000 %BOOT% 0x8000 %PART% 0xe000 %APP% 0x10000 %PROG%
pause

The name of the actual file programmed into the M5Stack device was replaced above by “PROGRAM.ino” Telling the IDE to save the compiled binary will put this file, along with the bootloader and partition configuration into your current working directory.

Next, you can see that we redirect the output of chgport to a file, then set a variable PORTLINE to the content of that file. The next line strips out the first 5 characters and stores it in the PORTNAME variable. This imposes an important requirement for using this batch script: the Arduino device must be the only, or at least the first, COM port in the file. It’s possible to work around this limitation, but it would require a more complex batch file, or perhaps even a Python script or similar.

Assuming we can successfully get the COM port, the next line calls the esptool with the necessary parameters and the device is programmed. I added a “pause” command so the user can see the result of the script before the window disappears.

There you have it. HTH!




If you'd like to subscribe to this blog, please click here.

Categories
Arduino

Ready to ship

I love it when a project comes together nicely.

M5 Stack has some really great hardware and made this project so much smoother. 12V input signal with local status displayed on screen and also communicated to App via BLE! All based on the M5Stack Tough units.




If you'd like to subscribe to this blog, please click here.

Categories
Uncategorized

Arduino 10MR & 10MT PLC modules

I’ve been seeing these Arduino-based “PLCs” on the internet for a while. If you’re not familiar with PLCs, they are basically control computers with built-in or expandable Inputs and Outputs and are used for industrial control. They are typically hardened against accidental overload (too much current on the output or wrong polarity voltage on inputs) and run on 24VDC They’re built to work reliably in a harsh industrial environment. They are also usually quite expensive, although there are low-priced versions available, such as the Click PLC starting around $100 each.

There have been industrialized versions of Arduino-based controllers for years. I have built a few projects based on the Industruino, for example, and I quite like it.

But these new versions like the 10MT and the 10MR address the lower end of the market that doesn’t require that level of “toughness”. I was curious, so I picked up a couple. They’re cheap, right, so how can you go wrong?

10MR PLC

First impressions are that it looks pretty good. It’s mountable either by DIN rail or four screw holes in the feet. The material seems to be ABS plastic. Polycarbonate would have been nice. Programming is via a DE-9 serial port, so you will need to connect it to a serial port. A USB-to-serial converter should work just fine. The connections are by rising-cage screw terminals, which was a nice surprise. Most Arduino clone connectors use the super cheap and annoying terminals that can’t grip wire properly unless you use ferrules. I mean, these are cheap terminals, but not the bottom of the barrel. These actually work fairly well.

The module comes with four optically-isolated FET open-drain (aka “NPN”) power-driver outputs or relays, depending on the version you choose. Outputs are labelled Y0 through Y3 and are assigned to Arduino pins 9 – 12. The 10MR has relays and the 10MT has transistors. There are also 6 digital inputs and 3 analog inputs and a 2-line, 16 character LCD. The units specify a 24VDC power supply, but I have successfully run them from 12V also.

Overview

So far I’ve only used the outputs on the 10MR and aside from a momentary surprise — the outputs are fully isolated, so you need to supply a ground and power to the load, it worked immediately to drive my test solenoid. Since it’s Arduino powered, it’s easy to control using the standard Arduino API commands.

Having a display is a really nice plus, but it would be even better if there were a few pushbuttons. However, those are easy enough to add with the many digital inputs. I put together a demo platform with a power supply and a pushbutton mounted to a short piece of DIN rail and the PLC screwed directly to a panel. For output, I have a small stacklight that I converted from incandescent lighting to LED.

I ran a test with a basic one-shot timer having a pushbutton input on X0 and an output on Y0. Here’s the code.

// Project sponsor: N/A
// Email: sales@cedarlakeinstruments.com
// Creator: Cedar Lake Instruments LLC
// Date: January 2023
//
// Description:
// Demonstrate one-shot logic with Arduino
// Tested on ZanhorDuino board
// 
// Arduino pins
// 9 - Digital trigger input. Pull LOW to trigger one shot
// 8 - One shot output (goes HIGH for one shot time)
//
//
// Test program for ZanhorDuino PLC
// NPN outputs are optically isolated so need their own V+ & GND connections
//

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27,16,2);  

// ********** U S E R  A D J U S T M E N T S ********************
// One shot time in milliseconds
const int DELAY_MS = 6000;
// **************************************************************

const int INTERVAL_MS = 100;
int _timeout = 0;
const bool OUTPUT_ON = false;
const bool OUTPUT_OFF = true;

// X0 is input
const int TRIGGER_PIN = 8;

// Y0 is output
const int OUT_PIN = 9 ;


void setup() 
{
    pinMode(TRIGGER_PIN, INPUT_PULLUP);
    pinMode(OUT_PIN, OUTPUT);
    digitalWrite(OUT_PIN, OUTPUT_OFF);

    lcd.init();
    // Print a message to the LCD.
    lcd.backlight();
    printStatus(DELAY_MS, LOW);   
}

void loop() 
{
    // One shot triggers on high->low transition of TRIGGER pin
    while (digitalRead(TRIGGER_PIN) == HIGH)
    {
        // Hold while pin not pressed
    } 

    // Activate output and start timing
    _timeout = DELAY_MS;
    digitalWrite(OUT_PIN, OUTPUT_ON);   

    // Hold output High until timeout 
    while ((_timeout-= INTERVAL_MS) > 0)
    {
        printStatus(_timeout, HIGH);
        delay(INTERVAL_MS);
    }

    // Turn output off
    digitalWrite(OUT_PIN, OUTPUT_OFF);
    // Update display
    printStatus(DELAY_MS, LOW);
}

// Prints remaining time and output status
void printStatus(int t, bool state)
{
    char buffer[17];
    // Pad to 16 characters: 12 for text (left-justified) 
    // and 4 for time (right-justified)
    sprintf(buffer,"%-12s%4d","TIME:",t/1000);
    lcd.setCursor(0,0);
    lcd.print(buffer);
    
    lcd.setCursor(0,1);
    state ? lcd.print("Output ON ") : lcd.print("Output OFF");
}

This works nicely. Press the pushbutton and the output turns on and the display shows a countdown in seconds until the output is back off.

When I have some more time, I’ll take a look at the analog inputs!




If you'd like to subscribe to this blog, please click here.

Categories
Uncategorized

What is an Embedded System and what does Arduino have to do with it?

An Embedded Computer System is a small computer that is “embedded” inside something else. Unlike a laptop computer, or a desktop, or a server, its primary purpose isn’t processing data, but it is meant to control some aspect(s) of the “thing” it’s embedded into. You probably don’t think of your clothes washing machine as a computer, but if it was built in the last 10 years, it almost certainly has an embedded computer controlling it. Likewise, the car or bus that takes you to work has dozens of embedded computers doing tasks as complex as sequencing the operation of the engine, or as basic as raising and lowering the windows.

How big are they?

A typical mainstream CPU (Central Processing Unit: the heart of the computer) such as an AMD Ryzen runs at a clock speed of almost 4GHz, requires more than 65W of power and has over 900 pins for external connections.

By contrast, the majority of embedded systems are based on microcontrollers. A microcontroller is a single package that houses a CPU, perhaps a basic clock source, some RAM memory to hold data and Flash storage for the program that it will execute, and peripherals that can read inputs like switches and pushbuttons, measure temperatures and voltages, and control output devices.

A basic AVR Mega microcontroller that might be found controlling the functions in your washer will run on substantially less than 1W of power, has a nominal clock speed of 8Mhz (but can run much slower to save power) and might require fewer than 20 pins to control such things as water flow, agitator cycling or spinning at the end of cycle. The microcontroller in your toothbrush might only have 6 pins and could run for years on a single AAA cell if necessary.

At the other end of the spectrum, more modern 32-bit microcontrollers have 1M+ of Flash memory and 256kb of RAM. Some microcontrollers can access external memory , further expanding their usefulness.

Why use them?

The benefit that an embedded system has over using logic “chip” to do their operations as was more popular in the past is primarily that a single low-cost chip can replace potentially dozens of external chips, thereby saving space, power and, of course, money. Additionally, a manufacturer may base a number of their products on a single microcontroller type, thereby saving on inventory costs and training. Since microcontrollers are computers at their heart, they can be reprogrammed to perform functions specific to the product they are embedded into.

Where does Arduino come in?

The Arduino is a basic microcontroller platform that was initially intended to offer artists and hobbyists a simple way to get involved in embedded systems. It has expanded from its basic roots to become a huge Open Source ecosystem of programming tools, libraries that make it easy to program unique functionality and add-on hardware that offers motion control, temperature and humidity measurement, multicolor LED displays, sophisticated graphics and so on.

Arduino continues to be a great way to get your feet wet in programming embedded systems.




If you'd like to subscribe to this blog, please click here.

Categories
Uncategorized

Basic wire crimping for arduino users

I keep posting information on crimpers and crimping, so I’m just going to put this here so I can refer to it without having to type it all in again 🙂

Crimping is a far more specialized and precise operation than it appears at first glance.

First, you need good quality tooling. Crimp dies have to be made specifically for the terminal to work ideally and wire length and wire insulation thickness are critical. That said, I have had fairly good luck with some cheap crimpers, but it’s hit and miss.

If you find that you’re having to “pre-crimp” anything before you can get the terminal into the die, then that’s a problem. That suggests that the die you have is not made for that terminal. Likewise, if the wires are slipping out. A good crimp cold welds the wire to the terminal and should require pounds of force (at least a firm pull) before the wire pulls out.

The basic technique is to put the terminal into the die and squeeze the crimper just enough to hold it in place. Next, put the stripped wire into the terminal, making sure it’s at the right depth and that the insulation ends at the right spot.

Then squeeze until the crimper completely closes and the ratchet releases so you can open it again. Inspect the crimp (the book I link below shows what various crimps should look like), and pull gently on the wire, holding the terminal in your other hand. A crimp for wire around 26-22gage should withstand at least a 5-lb pull, ideally a lot more, before it separates.

This book has everything you need to know about crimping and more.
Molex/TE Connectivity actually has a shorter book with good tips about crimping, but I can’t find it online at the moment.




If you'd like to subscribe to this blog, please click here.

Categories
Arduino

Your first Arduino program

So you’ve been hearing about this Arduino thing and you made the jump and downloaded the IDE since it’s a good first step and doesn’t cost anything. Now what?

Well, first of all, what’s an “IDE?” An IDE is an abbreviation for Integrated Development Environment. To write code you need a text editor and to program the Arduino device, you need a programmer. The “I” in Integrated means that the application contains both an editor and a programmer. The Arduino IDE is a very basic one but it gets the job done.

So, what’s a “sketch?” A sketch is the Arduino terminology for a computer program, which is the set of instructions you give a computer to tell it to do something. We also call this “code.” Why the Arduino inventors called a program a sketch I have no idea, but it seems to have stuck.

void setup()
{
}

The lines above are familiar to anyone who’s written an Arduino sketch. The basic outline of a sketch has two of these blocks called “functions.” A function is a short block of code that can be called, or told to execute from anywhere in your program. The other basic function is “loop” and we’ll get to it later. For now, the important thing to know is that setup is called when the program starts and loop is called repeatedly, over and over.

Since setup is called at the beginning, it’s the place where we put statements that need to be executed as soon as the Arduino starts up. e.g., we need to tell it which pins we want to use as inputs and outputs, what special configurations they need, and so on. Here’s a basic program that makes pins 2&3 outputs and blinks them five times.

void setup(void)
{
    // Set pins 2 and 3 as outputs
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);

    // Declare a variable for counting
    int i = 0;
    // Turn pins 2 & 3 off 5 times
    // using a for... loop
    for( i = 0; i < 5; i++ )
    {
        // Turn OFF pin 2
        digitalWrite(2, LOW);
        // Turn ON pin 3
        digitalWrite(3, HIGH);
        // Pause for 1000 milliseconds (1 second)
        delay(1000);

        // Turn ON pin 2
        digitalWrite(2, HIGH);
        // Turn OFF pin 3
        digitalWrite(3, LOW);
        // Pause for 1000 milliseconds (1 second)
        delay(1000);
    }
    // Turn OFF pin 2
    digitalWrite(2, LOW);
}

The short block of code above shows something important that’s often ignored: you can do real work in the setup() function. In fact, for some very short programs that just need to do a task and stop, it’s a good way to write your code.




If you'd like to subscribe to this blog, please click here.

Categories
Uncategorized

Sensors for counting objects

In order to count anything, we need to detect it first. This usually means some kind of sensor. The sensor used will typically provide a signal that our counter can read. Most such sensors actually function as a type of switch because their output terminals are closing a circuit on the counter electronics that causes a count to increment.

The simplest sensor used to count objects is an actual physical switch. Microswitches are switches with very sensitive contacts: a light touch is all it takes to register the presence of an object. Often microswitches are made with levers to reduce the force needed or to have a greater reach.

lever-switch

 

One common application for this type of switch is in coin counters for arcade games. The coin falls through a slot,  tripping the lever as it rolls past the switch. The main advantage of microswitches is their low cost and reliability. A disadvantage of this type of counting sensor is that physical contact with the switch is required and the force required to trip the sensor can affect the object you’re counting.

Another common sensor type used as input to counters or object detectors is a photoelectric switch. This optical sensor detects the interruption of a beam of light, often invisible infrared light. For example, to count boxes on a conveyor belt, an emitter, typically an infrared LED shines a focused beam of light across the belt. When the beam is reflected by an object passing by on the belt, the detector sees the returned light and closes a circuit and this sends a pulse to the counter module, updating the count of items going by.

photo

Optical sensors have the advantage of not requiring contact with the switch, but may not work well in dirty or dusty environments where the optical signal may be blocked. Also, this type of sensor used for counting reflective items can be “fooled” by multiple reflections, causing an inaccurate count. In this case, a through-beam sensor, where the item must pass between the LED emitter and its detector, is often more reliable.

Magnetic sensors, as their name claims, detect magnetic fields. They are very useful when a non-contact sensor is needed in a dirty environment where light may be blocked.

 

Now that we’ve got sensors to detect the items, our PRT232 counter module is the ideal interface to do the actual counting. We can make modifications to the basic counter, such as a display, or special RS232 signal outputs,


If you'd like to subscribe to this blog, please click here.

Categories
Arduino

Arduino Programming: Turn water on with Arduino and solenoid valve

Arduinos are popular small microcontroller boards that have many applications. However, they’re not designed to switch loads above a few milliamps: say a couple LEDs or so. While power-driver shields do provide this capability, they also can consume more resources than you may be able to give up.

We developed a high current driver to make it easy to control a solenoid valves with Arduino. It will also control pumps and motors. With an adapter cable, it can easily connect to your Arduino, BeagleBone, Raspberry Pi or other digital controller without soldering or crimping any connections. Doesn’t get any easier than that.

PwrDrvr1

The power driver board was born out of a need for controlling a 1 amp solenoid valve using an Arduino.  The solenoid valve was being used to control the water flow to fill a tank automatically. Now there’s a simple way to use your Arduino or compatible to switch up to 3A at 24VDC. Two output connections (the white wires shown above) connect directly the load (your solenoid, relay, motor, etc) and the power (red, black) go to the power supply (5 -24 volts). The orange lead is used to switch on and off. This is a low-voltage (5V) control that can connect directly to a microcontroller, or development board. An onboard LED indicates when the load is switched on.

Here’s some sample code that implements a timer with an Arduino. When the pushbutton is pressed, it turns on water flow for 3 seconds

// This sketch demonstrates a simple timer
// A load (motor, solenoid, relay, solenoid valve is on Pin 1
// A pushbutton to trigger the timer start is on pin 2
//
// When the pushbutton is held down for more than 0.1 second 
// then released, the timer starts
// and times out after 3 seconds
//
// Timer is retriggerable: if pushbutton pressed 
// during the timeout period, timer restarts
//
// Constant definitions
#define LOOP_INTERVAL 10
#define TIMEOUT 300 * LOOP_INTERVAL
#define TRIGGER_INTERVALS 10
#define TIMER_INACTIVE -1
#define TRIGGER_PIN 0
#define OUTPUT_PIN 1

void setup()
{
  pinMode(OUTPUT_PIN, OUTPUT);
  pinMode(TRIGGER_PIN, INPUT_PULLUP);
}

void loop()
{
  static int count = 0;
  static int timer = TIMER_INACTIVE;
  // Process loop periodically
  delay(LOOP_INTERVAL);
  
  // Check trigger input
  if (digitalRead(TRIGGER_PIN) == LOW)
  {
    // Must hold down pushbutton for the entire interval and 
    // then release to trigger
    count++;
  }
  else
  {
    // push button released. Check if we should start timing
    if (count >= TRIGGER_INTERVALS)
    {
      // Turn output ON (timeout is retriggerable)
      digitalWrite(OUTPUT_PIN, HIGH);
      timer = TIMEOUT;
    }
    count = 0;
  }
  
  // If timer active, count down
  if (timer != TIMER_INACTIVE)
  {
    timer -= LOOP_INTERVAL;
    if (timer == 0)
    {
      // Turn output OFF
      digitalWrite(OUTPUT_PIN, LOW);
      timer = TIMER_INACTIVE;
    }
  }
}      

Let’s find out what new applications you can come up with.


If you'd like to subscribe to this blog, please click here.