Friday, June 5, 2020

AMG8833 8x8 Thermal Camera with ESP8266 D1 Board and ILI9341 LCD


My latest project is to make a thermal camera.  Adafruit has lots of info on the AMG8833 8x8 thermal camera, as well as example software to use it with a ILI9341 LCD screen.

AMG8833 -> ESP8266 -> ILI9341LCD = Thermal Camera!

The Adafruit examples include an interpolated version.  Although the camera is 8x8 it calculates the colors between the pixels to yield many more pixels.  The Adafruit AMG8833 tutorial is here: 
https://learn.adafruit.com/adafruit-amg8833-8x8-thermal-camera-sensor

The drivers and example files are here:  https://github.com/adafruit/Adafruit_AMG88xx

I made this change to the interpolate example code:
#ifdef ESP8266
   #define STMPE_CS 16
   #define TFT_CS   D10
   #define TFT_DC   D9
   #define SD_CS    2
#endif

Here is the back side of the LCD.  I soldered jumpers to power, reset and LED to reduce the number of jumper wires needed to connect the LCD.

This is the AMG8833 Thermal camera.  IT takes four wires to connect to the processor.
AMG8833 Thermal camera
This picture shows the connections to the D1 processor board.  The left 2 wires are from the camera the right 4 wires go to the LCD.

The LCD is powered by 3.3 volts and the thermal sensor is powered by 5 volts only because there is no other 3.3 volt pin available.

Here is a video of it working:



I have added a display of the maximum temperature. Basically you create two variables, scan through the readings and pick the highest temperature, then convert it to Fahrenheit and display it.


Here are the changes that are needed to the demo code to find and display the peak temperature:

int HighTemp = 0;
int HTemp = 0;

void loop() {
  //read all the pixels
  amg.readPixels(pixels);

  Serial.print("[");
  HighTemp=0;
  for(int i=1; i<=AMG88xx_PIXEL_ARRAY_SIZE; i++){
    Serial.print(pixels[i-1]);
    Serial.print(", ");
    if( i%8 == 0 ) Serial.println();
    if (pixels[i-1] > HighTemp) HighTemp = pixels[i-1];
  }
  Serial.println("]");
  Serial.println();
  HTemp = ((HighTemp * 9/5) + 32);
  Serial.println (HTemp);
 
  float dest_2d[INTERPOLATED_ROWS * INTERPOLATED_COLS];

  int32_t t = millis();
  interpolate_image(pixels, AMG_ROWS, AMG_COLS, dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS);
  Serial.print("Interpolation took "); Serial.print(millis()-t); Serial.println(" ms");

  uint16_t boxsize = min(tft.width() / INTERPOLATED_COLS, tft.height() / INTERPOLATED_COLS);
 
  drawpixels(dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS, boxsize, boxsize, false);

  //delay(50);
}

void drawpixels(float *p, uint8_t rows, uint8_t cols, uint8_t boxWidth, uint8_t boxHeight, boolean showVal) {
  int colorTemp;
  for (int y=0; y<rows; y++) {
    for (int x=0; x<cols; x++) {
      float val = get_point(p, rows, cols, x, y);
      if(val >= MAXTEMP) colorTemp = MAXTEMP;
      else if(val <= MINTEMP) colorTemp = MINTEMP;
      else colorTemp = val;
     
      uint8_t colorIndex = map(colorTemp, MINTEMP, MAXTEMP, 0, 255);
      colorIndex = constrain(colorIndex, 0, 255);
      //draw the pixels!
      uint16_t color;
      color = val * 2;
      tft.fillRect(boxWidth * x, boxHeight * y, boxWidth, boxHeight, camColors[colorIndex]);
       
      if (showVal) {
        tft.setCursor(boxWidth * y + boxWidth/2 - 12, 40 + boxHeight * x + boxHeight/2 - 4);
        tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(2);
        tft.print(val,1);
      }
    }
  }
  tft.setTextSize(2);
  tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
  tft.setCursor(rows*boxWidth,0);
  tft.print(" High");
  tft.setCursor(rows*boxWidth,20);
  tft.print(" Temp:");
  tft.setCursor(rows*(boxWidth+1),40);
  tft.print(HTemp);
  tft.print(" ");
//  }
}

Friday, May 15, 2020

Arduino to Nokia 84x48 LCD Heartbeat Display

I am working on some Arduino biometric designs perhaps for a new book. So far I have created the two line 1602 LCD display and now the Nokia 84x48 display.  The Nokia display is more fun to work with since I can do a oscilloscope like display across the screen.  I am working on writing code that works with both an Arduino UNO and with the ESP8266 or the "D1" board.

You can connect a NOKIA display easily using a header extender.  You only need to connect five pins this way.  The other two are power and ground and they use jumpers to 3.3 Volts and ground.

This is what the connections look like from above. Note that I have a 100 ohm resistor to power the LED back light connected across the two outside pins.

This is a close up picture of the display.
This is a link to the video of it operating.
https://youtu.be/BjQTGu81Pvo

Here is the code:
// NOKIA Heartbeat
// Hearteat BPM displays on line 1
// Scope Trace of Heartbeat displays on lower 1/2
// By Bob Davis in April 2020

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(D7, D6, D5, D3, D4);

// Variables
int pulsePin = A0; // Pulse Sensor on analog pin 0
int blinkPin = D13; // pin to blink led at each beat
int StartSample = 0;// Start time MS
int EndSample = 0;  // End time MS
int rate[5];    // Array of samples in Milliseconds (MS)
int MS = 0;     // Milliseconds between pulses
int BPM;        // Beats Per Minute
int peak=800;   // Typical Peak voltage
int valley=500; // Typical Minimum voltage
int thresh=250; // Trigger threashold
int sens=70;   // Sensitivity to rise and fall of heartbeat
int Signal;     // Incoming raw data from heart sensor
int ypos=0;     // Trace Y axis
boolean Pulse = false; // "True" when heartbeat detected
int rateTotal = 0;

void setup(){
  Serial.begin(9600);
  display.begin();
  display.setContrast(50);
  display.clearDisplay();   // clears the screen and buffer
  pinMode(blinkPin,OUTPUT); // pin to blink with heartbeat
  pinMode(pulsePin,INPUT); // Configuring pin A0 as input
}

void loop(){
  Signal = analogRead(pulsePin);
  // Display values of BPM Signal on LCD
  display.fillRect(0,0,80,20,WHITE); //Clear top
  display.setCursor(0,0);  // First line
  display.println("BPM:");
  display.setCursor(24,0);  // First line
  display.println(BPM);
  display.setCursor(0,10);  // First line
  display.println("MS:");
  display.setCursor(24,10);  // First line
  display.println(MS);
  // Draw the trace of heartbeat
  display.drawPixel(ypos,(Signal/10)-40,BLACK);  // Bottom of LCD
  ypos=ypos+1;
  if (ypos>84) {
    ypos=0;
    display.clearDisplay();   // clears the screen and buffer
  }
  display.display();  // Update the screen

  // Find peak, valley and detect change in direction
  if (Signal > peak) peak=Signal;  // Find peak
  if (Signal < valley) valley=Signal; // Find valley
  if (Pulse == false) thresh = (valley+sens); // look for rise
  if (Pulse == true) thresh = (peak-sens);    // look for fall
  if ((Signal > thresh) && (Pulse == false)){ // Pulse Detected
    Pulse = true; // set Pulse flag
    digitalWrite(blinkPin,HIGH); // turn on pin 13 LED
  }

  if ((Signal < thresh) && (Pulse == true)){ // Pulse Finished
    Pulse = false; // reset Pulse flag
    digitalWrite(blinkPin,LOW); // turn off pin 13 LED
    EndSample = millis();
    MS = (EndSample-StartSample);
    StartSample = millis();
    // Reset peak and valley to center
    valley = valley+((peak-valley)/2);
    peak = valley+((peak-valley)/2);
    // BPM = 60000/MS;
    // Keep and average a running total
    rate[5] = rate[4]; // Shift the oldest MS values
    rate[4] = rate[3]; // Shift the oldest MS values
    rate[3] = rate[2]; // Shift the oldest MS values
    rate[2] = rate[1]; // Shift the oldest MS values
    rate[1] = MS; // add the latest MS to array
    rateTotal = (rate[1]+rate[2]+rate[3]+rate[4]+rate[5])/5; // Add up the MS values
    BPM = 60000/rateTotal; // Beats in a minute is BPM

    // display results on computer screen for troubleshooting.
    Serial.print("Beats Per Min=");
    Serial.print("\t");
    Serial.print(BPM);
    Serial.print("\t");
    Serial.print(rate[1]);
    Serial.println();
  }
  delay(10); // take a break
}

Thursday, April 30, 2020

Arduino Powered Colloidal Silver Maker

I have used a colloidal silver maker for years, but it was not mine, and the owner asked for it back.  Then I looked for my home made silver maker but could not find it.  Then I got an idea, make a colloidal silver maker powered by an Arduino so it could control the voltage, current, reverse the polarity, graph the results and time the operation.

This is my latest schematic.

There are now some filter capacitors in the circuit to attempt to get more stable numbers on the LCD display.  I have changed the resistors in the divider to 300K (Two 150K in series) and 100K to further reduce the current reading when no water is present.  Also note that the stirrer motor is now on D3 for PWM ability.  Eventually you might be able to adjust the stirrer voltage with a few key presses.  I have also made a small circuit board with the voltage and current monitoring resistors on it.  Its visible in some of the latest pictures.

This is the schematic showing the LCD wiring.  This is identical to the LCD shield wiring.



This is what the LCD screen looks like in an earlier version.  I could use a bigger screen!  The LCD is saying the voltage is .51 volts and .25 volts across a 1K ohm resistor for a current of .25ma, it never reaches 1 ma during over 4 hours of operation.  Every 30 minutes the Arduino reverses the polarity and the LCD will then show around 17.7 volts.  The bottom line has the run time.

This is what the LCD looks like after over 30 minutes of operation, when the polarity is reversed.  The voltage and current bounce around a lot, likely because of the noise from the air pump motor.

Here is a picture of the colloidal silver maker, but it was running off USB power and the CS container was only half full.  This time the L293 board is visible on the right side of the picture.

This picture shows the Colloidal Silver Generator actually running.  The Air pump stirrer has been added with 20 ohms in series to reduce the motor noise.  Also the motor ground must be separate from the other grounds because of all the electrical noise that the motor makes.
Arduino Colloidal Silver Maker
Here is another picture.  The resistor divider and L293 motor controller are now located on the top of the colloidal silver maker.  Eight wires then run down to the Arduino.  There are two ground wires, one ground wire for the motor controller and one ground wire for the voltage divider.

After the second test run with the current staying under .5 ma, and 1 ma being the ideal current, I am thinking that it needs to to be modified from 12 volts to 20 volt operation.  Most Colloidal silver makers use 24 to 28 volts. The L293 can operate up to 30 volts, but the Arduino voltage regulator has a maximum of 20 volts, and the air pump stirrer has a maximum of 12 volts. The air pump runs best at around 9 volts.  So either a redesign will be needed to have some voltage regulators added, or I can try to use a 20 volt power source like that of an old laptop ac adapter.

I tested this design for a few minutes with a 19 volt laptop AC adapter.  Only 17.7 volts made it to the colloidal silver maker.  The Arduino voltage regulator got very warm but survived.  I disconnected the air pump for this test because it is rated for 12 volts maximum and runs best at 7-9 volts.  I have since added a PWM output from the Arduino for the air pump of 1/2 of the power source or 10 volts for 20 volt operation.

The Arduino's PWM ability is used to regulate the current to the Colloidal Silver maker to just under 1 ma. The over current shutdown is set to 2.0 ma.

There is a video of it running at this link: https://youtu.be/3ap4-GnGx_8

Here is the code so far:

/*****************************
Arduino Colloidal Silver Maker
By Bob Davis
April 2020

Use a 16x2 LCD display shield or equivalent
Shows the voltage, current, and run time.

The circuit:
 * LCD RS - D9
 * LCD Enable - D8
 * LCD D4 - D4
 * LCD D5 - D5
 * LCD D6 - D6
 * LCD D7 - D7
 * LCD R/W and VSS pin to ground
 * LCD VCC and LED pin to 5V
 * 10K variable resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 * Uses L293 motor controller on D10 adn D11 for PWM ability
 * Uses L293 on D3 for stirrer motor.

*********************/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the

interface pins
LiquidCrystal lcd(9, 8, 4, 5, 6, 7);

// Pins for Colloidal silver maker
int CS1=10;
int CS2=11;
// Pins for stirrer
int Stir=3;
int Shutdown=0;
// Variables for time
int hours;
int minutes;
int seconds;
long hour = 3600000; // 3600000 milliseconds in an hour
long minute = 60000; // 60000 milliseconds in a minute
long second = 1000; // 1000 milliseconds in a second
float AN1=0.0; // Analog inut 1
float AN2=0.0;
float temp1=0.0;
float temp2=0.0;
float CUR=0.0;  // Current in ma
int CurSet=255; // Current Setting

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  pinMode (CS1, OUTPUT);
  pinMode (CS2, OUTPUT);
  pinMode (Stir, OUTPUT);
}

void loop() {
  // Reverse current every 30 minutes
  if (Shutdown==0){
    analogWrite(Stir, 128); // 1/2 supply voltage
    if (minutes<30){
      analogWrite(CS1, 0);
      analogWrite(CS2, CurSet);
    }
    else{
      analogWrite(CS2, 0);
      analogWrite(CS1, CurSet);
    }
  }
  else{
    analogWrite(CS1, 0);
    analogWrite(CS2, 0); 
    analogWrite(Stir, 0); 
    }
  temp1=analogRead(A1);
  AN1=((temp1*5.0)/1024.0)*4.0;
  temp2=analogRead(A2);
  AN2=((temp2*5.0)/1024.0)*4.0;
  CUR=abs(AN1-AN2);
  if (CUR > 1.0) {CurSet--;} // Reduce PWM
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("V:");
  lcd.print(AN1);
  lcd.setCursor(8,0);
  lcd.print("V:");
  lcd.print(AN2);
  lcd.setCursor(10,1);
  lcd.print("C:");
  lcd.print(CUR);
  // print the number of seconds since reset:
  long timeNow = millis();
  hours = (timeNow) / hour;             
  minutes = ((timeNow) % hour) / minute ;
  seconds = (((timeNow) % hour) % minute) / second;
  lcd.setCursor(0, 1);
  lcd.print("T:");
  lcd.print(hours);
  lcd.print(":");
  lcd.print(minutes);
  lcd.print(":");
  lcd.print(seconds);

  if (hours>3){ // Time under 4 hours
    Shutdown=1;
    }
  if (CUR>2.0){ // Current under 1ma
    Shutdown=1;
    }

  delay(300);
}

Tuesday, February 25, 2020

I am Making a DIY Clone of the CNC 3018

I recently built a CNC 3018 Pro for someone and blogged about it.  Now I have decided to rebuild my home made CNC to be like the 3018.

This picture compares the two machines side by side.
To be honest it would be cheaper to buy the kit on eBay.  I figured I had most of the parts so it would be cheaper but that is not the case!  If you bought all of the parts it would cost you over $200 and you can get the kit on eBay for around $140-150.

This picture shows how I wired the 3018 CNC

CNC 3018 wiring
 Using larger sized limit switches with a piece of 2" by 1" angle aluminum.
 More limit switch pictures.  I had a limit switch that had a sideways lever for the Z axis.
 Close up of smaller limit switches.  I could only get one screw because of the Allen screw that tightens against the rod.  I should have put the switch on the other side so the rods can be removed.
The controller board needs lots of repairs and even a software fix. You need to add pull up resistors to the inputs of the Pololu A4988 Stepper controllers.  Don't forget to remove the jumpers on the other side of the board as well.  Then you will need to add filter caps to D9, D10 and D12. The board has D11 as the Z axis limit switch but GRBL will use D12 instead.  D11 is used for the spindle control relay or transistor.  In software the "Step" and "Direction" pins are all swapped and need to be swapped back.  There are several web sites that tell how to do that.

Monday, January 27, 2020

DIY CNC 3018 Adding Limit Switches

I am in the process of adding some limit switches to a CNC3018.  It can be done without any adapters.  For the Y axis I used some 3/4 inch 4-40 screws.  The screw head goes through a washer that is cut flat on one side, so it can fit in the T slot groove.  Then a large bolt goes into the slot of the platform.  Something square would make the switch levers hit more evenly.  I might make something out of aluminum for that purpose.
This is the completed, front Y axis switch with a aluminum square block on the bolt.
CNC 3018 Pro Y Limit Switch

Here are pictures of the first X limit switches.  These were later changed to smaller switches like the ones used on the Z axis.


This is the Z axis limit switch.  It is required as the Z axis is tested first.

This is how a major website shows to wire the CNC 3018 PRO.  This is TOTALLY wrong!  The platform will crash when it tries to go back because the wires and wire ties are in the way..
Here is how I wired my CNC 3018.  I used some black electrical tape to cover the wires from the Y axis stepper motor.  The wires to the X axis stepper are folded in thirds within the wire wrap.

 This is how I wired the Z axis.  This works quite well and allows the cable to move freely.
CNC 3018 Pro Z axis Wiring

I improved the wiring harness and the X axis limit switches.  The wiring harness now looks like, and could be, one continuous piece.
CNC 3018 Pro Wiring

The new X axis limit switches are micro switches like the one I used for the Z axis.  The biggest problem with these switches is that a 4-40 screw is too big.  You need a 2-56 screw.  I found some screws that came with servos for use with the servo horns.
CNC 3018 Pro X and Z limit switches

It is finally working!


The problem was calibrating the driver voltage/current.  With a voltmeter on ground and on the center of the trimmer adjust for .7 to .8 volts.  That results in 1.4 to 1.6 amps to the coils and much cooler drivers.  If you do not have a voltmeter and are using 8825 drivers set the trimmers to match this picture or to about 45 degrees to the right of straight up.


This is a picture zoomed in on the trimmers.

Here is the code to work with the limit switches and to make "home" the 0,0 position.

$0=10;
$1=25;
$2=0;
$3=5;
$4=0;
$5=0;
$6=0;
$10=1;
$11=0.010;
$12=0.002;
$13=0;
$20=1;
$21=0;
$22=1;
$23=3;
$24=25.000;
$25=500.000;
$26=250;
$27=2.000;
$30=1000;
$31=0;
$32=0;
$100=1600.000;
$101=1600.000;
$102=1600.000;
$110=1000.000;
$111=1000.000;
$112=800.000;
$120=30.000;
$121=30.000;
$122=30.000;
$130=300.000;
$131=180.000;
$132=40.000;

After going to "home" set the Z axis down to the surface and then set the X, Y and Z to "0".

Tuesday, January 14, 2020

I gave in and built a CNC 3018 DIY CNC Kit.

Building the CNC 3018 DIY kit.  This is how it arrived in the box.  I purchased it slightly used, so some parts were not in their normal locations in the box.

This is the electrical parts that came with the kit.  It is missing the cover and fan for the controller.


This is the smaller mechanical parts.


This is the larger mechanical parts.


This is the bottom side of the base once it was assembled.  Make sure it is not skewed by running all the way to one end before tightening the screws.


This is the top view of the assembled base.

At this point I did not take any more pictures until after it was assembled.  The wire wrap was added after this picture was taken.

This is the front top view of the assembled 3018 CNC.  It only takes about one hour to assemble this CNC kit!

This picture compares the size of the Z axis to my homemade CNC.  The DIY Z axis on the right is as small as I could make it.

After several attempts to get the CNC to work, I determined that the CNC Controller board was toast.  I removed it and removed two of the motor jacks for this next picture.  So now I am looking to repair it or replace it.


Tuesday, December 31, 2019

90 x 16 Addressable LED sign with Arduino Uno and Bluetooth

I have added the ability to select the background color to my LED sign software.  The format is 080100 TEXT.  The numbers are for RGB foreground colors and RGB background colors.  Our cat Momo photobombed one of my video shoots.


Here is the video:


This is a picture of the controller.  The Bluetooth module is plugged directly into D0 and D1 at the top.  The network jack has eight 330 ohm resistors in series.  Power comes in on the Vin and ground pins.
The strips come in rolls of five meters or 16.4 feet and need to be cut into 4 or 5 foot lengths depending on the size of the sign.
Here I am adding the strips to a sign board background.

This is the back side of the sign. Power comes into all 16 LED strips but the lower eight have their data from the other side of the top eight strips.  There are two power connectors for five volts at 15 amps each.  You can connect them together to a 5 volt 30 amp power supply.

 This is the eight data wrap around lines from the top eight strips going to the lower eight strips.

This next picture is of some LED strip lights decorating some windows.  I used automotive trim tape to hold the strips in place

Here are two pictures of one of my signs in a store window.

Here is another Video showing some new features.