Pages

Showing posts with label Raspberry Pi. Show all posts
Showing posts with label Raspberry Pi. Show all posts

Monday, February 17, 2025

Weather

 


This is the temporary installation of my Anemometer & Wind Vane to test via RS-485 into a couple of ESP-32's. The outside temp is currently -30C so I'm not in any hurry to mount these up higher where they will be unobstructed!

Here is the pic of the 12V supply feeding a buck converter down to 5VDC to feed both ESP32's, one for the Anemometer and one for the Wind Vane. Buck converter in the centre under the white CAT5 cable that feeds 12VDC power to the devices and brings back 2 wires each RS485 to the RS485>TTL converters (top & bottom of photo). You can see one of the ESP32's with the green tape showing 00 on it.



You are supposed to be able to change the addresses on the devices (they all default to 1) so that they can share the same RS485 buss, but the documentation is sparse on these units and rather than take the chance that I 'brick' them, I'm leaving the addresses alone. Which means that I now have 3 devices (Anemometer, Wind Vane & Temperature/Humidity Sensor that are all RS485.

After receiving my Raspberry Pi Pico 2W's I started reading the documentation and found that the PIO function allows for additional UART's (it comes with 2), so I wrote a sketch to talk to 3 RS485>TTL boards from the 2 UARTs and 1 SoftwareSerial PIO-based UART

Here is a line diagram of the original circuit before I added the Pico, third TTL>RS485 board & Temp/Humidity Sensor


/* 

 *  TempHumidRS485_3.ino

 *  Robin Greig

 *  2025.02.17

 *  

 *  Reads the Temp & Humidity of RS485 device and prints it to Serial Monitor

 *  

 *  Using both UARTS and PIO-based UART to read 3 RS485 > TTL inputs

 *  mySerial1 = Rx / Pin 2 / GPIO 1 & Tx / Pin 1 / GPIO 0

 *  mySerial2 = Rx / Pin 7 / GPIO 5 & Tx / Pin 6 / GPIO 4

 *  mySerial3 = SerialPIO = Tx / Pin 11 / GPIO 8 & Rx / Pin 12 / GPIO 9

 *  

 *  Addint mqtt connectivity

 *  

 *  Based on the ModbusMaster example below

*/


#include <ModbusMaster.h>       //https://github.com/4-20ma/ModbusMaster

#include <SoftwareSerial.h>


#include <WiFi.h> 

#include <PubSubClient.h>

#include <string.h>


// Create a SoftwareSerial object to communicate with the MAX485 module

SoftwareSerial mySerial1(1, 0); // Rx-Pin 2-GPIO 1 & Tx-Pin 1-GPIO 0

SoftwareSerial mySerial2(5, 4); // Rx-Pin 2-GPIO 1 & Tx-Pin 1-GPIO 0

SerialPIO mySerial3(8, 9); // Tx-GPIO 8-Pin 11 & Rx-GPIO 12-Pin 10

//for SoftwareSerial PIO-based UART


// Create a ModbusMaster object

ModbusMaster node1;

ModbusMaster node2;

ModbusMaster node3;


// WiFi 


const char *ssid = "Calalta02"; // Enter your WiFi name 


const char *password = "Micr0s0ft2018";  // Enter WiFi password 


// MQTT Broker 


const char *mqtt_broker = "192.168.200.143"; 


const char *topic1 = "pico2w/00/temp1";

const char *topic2 = "pico2w/00/humid1";  

const char *topic3 = "pico2w/00/temp2";

const char *topic4 = "pico2w/00/humid2";  

const char *topic5 = "pico2w/00/temp3";

const char *topic6 = "pico2w/00/humid3";  


const int mqtt_port = 1883; 


WiFiClient espClient; 


PubSubClient client(espClient); 


float humidity1;

char humidChar1 [6];

float humidity2;

char humidChar2 [6];

float humidity3;

char humidChar3 [6];

float temperature1;

char tempChar1 [6];

float temperature2;

char tempChar2 [6];

float temperature3;

char tempChar3 [6];


void setup() {


  // Initialize serial communication for debugging

  Serial.begin(115200);

  // Initialize SoftwareSerial for Modbus communication

  mySerial1.begin(9600);

  mySerial2.begin(9600);

  mySerial3.begin(9600);

 

  // Initialize Modbus communication with the Modbus slave ID 1

  node1.begin(1, mySerial1);

  node2.begin(1, mySerial2);

  node3.begin(1, mySerial3);


  WiFi.begin(ssid, password); // connecting to the WiFi network 


  while (WiFi.status() != WL_CONNECTED) { 


      delay(500); 


      Serial.println("Connecting to WiFi.."); 


  } 


  Serial.println("Connected to the WiFi network"); 


  //connecting to a mqtt broker 


  client.setServer(mqtt_broker, mqtt_port); 


  while (!client.connected()) { 


      String client_id = "pico2w-00 > "; 


      client_id += String(WiFi.macAddress());


      Serial.printf("The client %s is connecting to the mqtt broker\n", client_id.c_str()); 


//      if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { 

      if (client.connect(client_id.c_str())) { 


          Serial.println("Mqtt broker connected"); 

          

      } else { 


          Serial.print("failed with state "); 


          Serial.print(client.state()); 


          delay(1000); 


      } 

 

  // Allow some time for initialization

  delay(500);

  }

void loop() {

  uint8_t result1;   // Variable to store the result of Modbus operations

  uint16_t data1[2]; // Array to store the data read from the Modbus slave

  uint8_t result2;   // Variable to store the result of Modbus operations

  uint16_t data2[2]; // Array to store the data read from the Modbus slave

  uint8_t result3;   // Variable to store the result of Modbus operations

  uint16_t data3[2]; // Array to store the data read from the Modbus slave

 

  // Read 2 holding registers for node1 starting at address 0x0000

  // This function sends a Modbus request to the slave to read the registers

//  result1 = node1.readHoldingRegisters(0x0000, 2);

  result1 = node1.readHoldingRegisters(0x0000, 2);

 

  // If the read is successful, process the data

  if (result1 == node1.ku8MBSuccess) {

    // Get the response data from the response buffer

    data1[0] = node1.getResponseBuffer(0x00); // Humidity

    data1[1] = node1.getResponseBuffer(0x01); // Temperature

 

    // Calculate actual humidity and temperature values

    humidity1 = data1[0] / 10.0;      // Humidity is scaled by 10

    temperature1 = data1[1] / 10.0;   // Temperature is scaled by 10

 

    // Print the values to the Serial Monitor

    Serial.print("Humidity1: ");

    Serial.print(humidity1);

    Serial.println(" %RH");

 

    Serial.print("Temperature1: ");

    Serial.print(temperature1);

    Serial.println(" °C");

    Serial.println();

  } else {

    // Print an error message if the read fails

    Serial.print("Modbus read failed: ");

    Serial.println(result1, HEX); // Print the error code in hexadecimal format

    Serial.println();

  }

  delay(200);

  // Read 2 holding registers for node2 starting at address 0x0000

  // This function sends a Modbus request to the slave to read the registers

  result2 = node2.readHoldingRegisters(0x0000, 2);

 

  // If the read is successful, process the data

  if (result2 == node2.ku8MBSuccess) {

    // Get the response data from the response buffer

    data2[0] = node2.getResponseBuffer(0x00); // Humidity

    data2[1] = node2.getResponseBuffer(0x01); // Temperature

 

    // Calculate actual humidity and temperature values

    humidity2 = data2[0] / 10.0;      // Humidity is scaled by 10

    temperature2 = data2[1] / 10.0;   // Temperature is scaled by 10

 

    // Print the values to the Serial Monitor

    Serial.print("Humidity2: ");

    Serial.print(humidity2);

    Serial.println(" %RH");

 

    Serial.print("Temperature2: ");

    Serial.print(temperature2);

    Serial.println(" °C");

    Serial.println();

  } else {

    // Print an error message if the read fails

    Serial.print("Modbus read failed: ");

    Serial.println(result2, HEX); // Print the error code in hexadecimal format

    Serial.println();

  }

  delay(200);

  // Read 2 holding registers for node3 starting at address 0x0000

  // This function sends a Modbus request to the slave to read the registers

  result3 = node3.readHoldingRegisters(0x0000, 2);

 

  // If the read is successful, process the data

  if (result3 == node3.ku8MBSuccess) {

    // Get the response data from the response buffer

    data3[0] = node3.getResponseBuffer(0x00); // Humidity

    data3[1] = node3.getResponseBuffer(0x01); // Temperature

 

    // Calculate actual humidity and temperature values

    humidity3 = data3[0] / 10.0;      // Humidity is scaled by 10

    temperature3 = data3[1] / 10.0;   // Temperature is scaled by 10

 

    // Print the values to the Serial Monitor

    Serial.print("Humidity3: ");

    Serial.print(humidity3);

    Serial.println(" %RH");

 

    Serial.print("Temperature3: ");

    Serial.print(temperature3);

    Serial.println(" °C");

    Serial.println();

  } else {

    // Print an error message if the read fails

    Serial.print("Modbus read failed: ");

    Serial.println(result3, HEX); // Print the error code in hexadecimal format

    Serial.println();

  }


  client.loop();

  //client.publish(topic, temperatureTest ); //publish temp 

  sprintf(tempChar1,"%.2f", temperature1);

  Serial.print("tempChar1 = ");

  Serial.println(tempChar1);

  client.publish(topic1, tempChar1); //publish temp

  sprintf(humidChar1,"%.2f",humidity1);

  Serial.print("humidChar1 = ");

  Serial.println(humidChar1);

  client.publish(topic2, humidChar1); 


  sprintf(tempChar2,"%.2f", temperature2);

  Serial.print("tempChar2 = ");

  Serial.println(tempChar2);

  client.publish(topic3, tempChar2); //publish temp

  sprintf(humidChar2,"%.2f",humidity2);

  Serial.print("humidChar2 = ");

  Serial.println(humidChar2);

  client.publish(topic4, humidChar2); 


  sprintf(tempChar3,"%.2f", temperature3);

  Serial.print("tempChar3 = ");

  Serial.println(tempChar3);

  client.publish(topic5, tempChar3); //publish temp

  sprintf(humidChar3,"%.2f",humidity3);

  Serial.print("humidChar3 = ");

  Serial.println(humidChar3);

  client.publish(topic6, humidChar3); 


  // Wait for 2 seconds before the next read

  delay(2000);

}




Sunday, February 16, 2025

RS485 Modbus to Raspberry Pi Pico 2W

 


A while ago I went to order a wind vane and Anemometer online and didn't pay attention and ended up receiving RS485 units rather than the 0-10VDC units I wanted....grin

This gave me the incentive to learn how to connect RS485 devices to ESP8266's, ESP32's and in this case a new Raspberry Pi Pico 2W that had just arrived.

Here is the TTL > RS485 board I am using:


The wind vane and Anemometer are already outside so I ordered a couple of Temperature & Humidity sensors that you see here to continue to experiment with the RS485 protocol. On the breadboard you can see the Pico 2W on the left and then side by side is the TTL > RS485 board and a RFID-RC522 board that I've been playing with on the Arduino Uno shown at the top of the picture.

I wasn't able to connect a RS485 device to a ESP8266 since, as I understand it, the main UART is used for the serial USB communication and the second UART is transmit only? So in the case of the wind vane and Anemometer I used a couple of ESP32's. Normally you can connect multiple RS485 devices on the same bus as long as you set unique addresses on each, however I haven't done that yet, so I connected each device to it's own ESP32. 

Given the low cost of the Pico 2W from  pishop.ca I was able to use the same software from the Arduino Modbus sketch and just change the Tx & Rx pin assignments.

The next step will be to add wireless & mqtt code to the Pico 2W so that it can transmit the temperature and humidity values to my mosquitto broker to be read by Node-Red on my Raspberry Pi

Thanks for reading!

Here is the code:

/* 

 *  TempHumidRS485a.ino

 *  Robin Greig

 *  2025.02.15

 *  

 *  Reads the Temp & Humidity of RS485 device and prints it to Serial Monitor

 *  

 *  Based on the ModbusMaster example below

*/



#include <ModbusMaster.h>       //https://github.com/4-20ma/ModbusMaster

#include <SoftwareSerial.h>

 

// Create a SoftwareSerial object to communicate with the MAX485 module

SoftwareSerial mySerial(1, 0); // RX, TX

 

// Create a ModbusMaster object

ModbusMaster node;

 

void setup() {

  // Initialize serial communication for debugging

  Serial.begin(115200);

  // Initialize SoftwareSerial for Modbus communication

  mySerial.begin(9600);

 

  // Initialize Modbus communication with the Modbus slave ID 1

  node.begin(1, mySerial);

 

  // Allow some time for initialization

  delay(1000);

}

 

void loop() {

  uint8_t result;   // Variable to store the result of Modbus operations

  uint16_t data[2]; // Array to store the data read from the Modbus slave

 

  // Read 2 holding registers starting at address 0x0000

  // This function sends a Modbus request to the slave to read the registers

  result = node.readHoldingRegisters(0x0000, 2);

 

  // If the read is successful, process the data

  if (result == node.ku8MBSuccess) {

    // Get the response data from the response buffer

    data[0] = node.getResponseBuffer(0x00); // Humidity

    data[1] = node.getResponseBuffer(0x01); // Temperature

 

    // Calculate actual humidity and temperature values

    float humidity = data[0] / 10.0;      // Humidity is scaled by 10

    float temperature = data[1] / 10.0;   // Temperature is scaled by 10

 

    // Print the values to the Serial Monitor

    Serial.print("Humidity: ");

    Serial.print(humidity);

    Serial.println(" %RH");

 

    Serial.print("Temperature: ");

    Serial.print(temperature);

    Serial.println(" °C");

    Serial.println();

  } else {

    // Print an error message if the read fails

    Serial.print("Modbus read failed: ");

    Serial.println(result, HEX); // Print the error code in hexadecimal format

  }

 

  // Wait for 2 seconds before the next read

  delay(5000);

}

Sunday, April 7, 2019

I finally got around to installing a set of fuses and a terminal strip on an old computer power supply that I had. 3.3V @ 20A, 5V @ 16A, 12V @ 16A, thus the need for fuses! I also added a small digital voltage regulator that you can see in the bottom left of the pic, so I have a variable power supply that I can step down to a specific voltage if necessary.
Thanks for viewing!
Robin

Sunday, July 9, 2017

Raspberry Pi 3 Alarm System

What is this mess, you might ask?

Well this is the final prototype for my Raspberry Pi 3 Alarm system. It uses the USB keypad in the upper left corner to input the correct code, the entry and exit delay beeper is in the lower left of the photo beside the keyboard, and the LED's showing what is going on is on the breadboard just above the keyboard. You cannot see the PIR sensors, that I have mounted on the pole of the shelf that is visible in the upper right of the picture.

The next step (today) is to mount all of the components on a board and see how everything will fit into the case!

I'll post a final pic once I have everything mounted in the case.

Thanks for viewing!
Robin

Sunday, April 30, 2017

Connecting Raspberry Pi 3 and Arduino

WOW, I cannot believe that it has been over a year since my last post. Time flies when you're having fun!!!

I've decided it was time to update the last post (it's only been about 16 months!)


  1. Install Jesse Raspbian with Pixel 2017-04-10
  2. Go thru the configuration
    1. Change the pi password
    2. Change the Pi Hostname
    3. Don’t automatically login to ‘pi’ user
  3. Under the Interfaces Tab:
    1. Camera = Disable
    2. SSH = Enable
    3. SPI = Enable
    4. I2C = Enable
    5. Serial = Disable
  4. I don't change anything under the Performance Tab
  5. Under the Localisation Tab:
    1. Change the locale to Canada (English)
    2. Set the Timezone to Canada (America) > Mountain (Edmonton)
    3. I’m still having a problem with changing the keyboard layout
      1. It is a noted problem on the Raspberry Pi Forum
      2. Still using sudo raspi-config to config to Canada > English
  6. sudo apt-get update
  7. sudo apt-get upgrade
  8. sudo adduser robin
  9. add robin to same groups as pi user (dialout for arduino)
  10. sudo apt-get install arduino
  11. sudo apt-get install arduino-mk
  12. Modify avrdude.conf to work with GPIO pins
    1. sudo nano /etc/avrdude.conf
    2. Ctrl-W to find the gpio reference, and uncomment the following lines
    3. programmer
      1. id = "linuxgpio";
      2. desc = "Use the linux sysfs interface to bitbang GPIO lines";
      3. type = "linuxgpio";
      4. reset = ?;
      5. sck = ?;
      6. mosi = ?;
      7. miso = ?;
      8. ;
    4. And change the ? to;
      1. reset = 8 (GPIO # not Actual pin #24, CE0)
      2. sck = 11 (Actual pin #23, SCLK)
      3. mosi = 10 (Actual pin #19, MOSI)
      4. miso = 9 (Actual pin #21, MISO)
    5. Wire up the Arduino ICSP header as follows:
      (RESET is closest to IC)
      -------------------
      | MISO    +5V |
      | SCK     MOSI |
      | RESET  GND |
      -------------------
      1. RESET to Raspi pin 24
      2. SCK to Raspi pin 23
      3. MISO to Raspi pin 21
      4. +5V to Raspi pin 2
      5. MOSI to Raspi pin 19
      6. GND to Raspi pin 6
    6. Type in sudo avrdude -v to ensure avrdude is responding
    7. Type in sudo avrdude -p atmega328p -c linuxgpio -v to ensure avrdude can communicate with the arduino
    8. As mentioned in my previous post, I copy my raspi-git github directory to each Raspi to make it easier to copy common files back and forth.
    9. cp -r ~/raspi-git/Uno/Blink ~ (to copy the blink directory to my home directory)
    10. move to the ~/Blink directory and run the following to download the software into the arduino
      1. sudo avrdude -p atmega328p -c linuxgpio -v -U flash:w:./build-uno/Blink.hex:i
      2. If all goes well this should upload the Blink.hex program to the arduino
    11. Check the Makefile for the following lines:
      1. BOARD_TAG = uno
      2. ARDUINO_PORT = /dev/ttyACM0
      3. ARDUINO_LIBS =
      4. ARDUINO_DIR = /usr/share/arduino
      5. include /usr/share/arduino/Arduino.mk
    12. Check it by modifying the ~/Blink/Blink.ino file and recompiling it
      1. nano ./Blink/Blink.ino
      2. Change the blink rate
      3. Ctrl-x to save
      4. make
      5. sudo avrdude -p atmega328p -c linuxgpio -v -U flash:w:./build-uno/Blink.hex:i
      6. the changes should be apparent on the Arduino LED

Wednesday, December 16, 2015

Avrdude 6.1

I just installed the latest version of Raspbian Jessie 2015-11-21 for my Pi 2's. I found that now when I installed the arduino package, it comes with avrdude 6.1. So I don't need to link to the adafruit repository anymore. Here is a list of the steps I take to install Jessie, Arduino, Arduino-mk, and check that I can communicate between the Arduino & Raspberry Pi 2 via Serial. You'll note that I clone my git repository where I keep all of my files as I'm working on them. I find this extremely useful since I'm working on the files on my Pi2 or Gertduino/PiB at home, or the same setup that I have at work:
  1. Install Jesse 2015-11-21
  2. Go thru the configuration
    (Menu > Preferences > Raspberry Pi Configuration)
    1. Under the System Tab:
      1. Expand the filesystem
      2. Change the pi password
      3. Change the Pi Hostname
      4. Don’t automatically login to ‘pi’ user
    2. Under the Interfaces Tab:
      1. Camera = Disable
      2. SSH = Enable
      3. SPI = Enable
      4. I2C = Enable
      5. Serial = Disable
    3. I don’t change anything under the Performance Tab
    4. Under the Localisation Tab:
      1. Change the locale to Canada (English)
      2. Set the Timezone to Canada (America) > Mountain (Edmonton)
      3. I’m still having a problem with changing the keyboard layout
        1. It is a noted problem on the Raspberry Pi Forum
        2. Still using sudo raspi-config to config to Canada > English
  3. sudo apt-get update
  4. sudo apt-get upgrade
  5. sudo adduser robin
  6. sudo visudo to give robin the same rights as pi user
  7. sudo apt-get install arduino-mk
  8. sudo apt-get install arduino (add robin to dialout group)
  9. Make a link to the Arduino.mk file:
    ln -s /usr/share/arduino/Arduino.mk ~/Arduino.mk
  10. Copy the original avrdude.conf file into my home directory
    1. cp /etc/avrdude.conf ~/avrdude_gpio.conf
  11. Modify it to work with the GPIO pins
    1. nano ~/avrdude_gpio.conf
  12. Aff the following lines at the end of the file:
    1. # Linux GPIO configuration for avrdude
    2. # Change the lines below to the GPIO pins connected to the AVR
    3. programmer
    4.  id = "pi_1";
    5.  desc = "Use the Linux sysfs interface to bitbang GPIO lines";
    6.  type = "linuxgpio";
    7.  reset = 12;
    8.  sck = 24;
    9.  mosi = 23;
    10.  miso = 18;
    11. ;
  13. With the Arduino connected to the Raspberry Pi, run the following line to make sure the Raspi can see the arduino:
    sudo avrdude -p atmega328p -C ~/avrdude_gpio.conf -c pi_1 -v
  14. cp -r ~/raspi-git/Python ~ (to copy the Python directory to my home)
  15. cp -r ~/raspi-git/Uno ~ (to copy the Uno directory to my home)
  16. Goto the .hex file @ ~/Uno/Serial/Voltages/build-uno/Voltages.hex & run:
    sudo avrdude -p atmega328p -C ~/avrdude_gpio.conf -c pi_1 -v -U flash:w:Voltages.hex:i
  17. If you overwrite the bootloader, reload it by going to:
    cd /usr/share/arduino/hardware/arduino/bootloaders/optiboot/
    and running the avrdude line with the optiboot_atmega328.hex file

Wednesday, December 9, 2015

Raspberry Pi takes over the world


OK, if not the world, then 1 outlet at a time!!!
This is a pic of a single relay that is controlled by my Raspberry Pi.
Red = 5VDC, Black = Ground, White = Pin23 (active high)
And an old pc power cord split in 1/2 and a female end installed.
The Ground and Neutral leads feed straight through from the input to the output
The relay switches the hot lead and runs a battery charger drawing 5 Amps AC.
The relay is rated for 10A @ 277V
The Raspberry Pi runs off of my solar array at home and because I have so many items tied to them:
     3 Raspberry Pi's
     1 x 12V HP switch
     1 x Kenwood HF Amateur Radio
     1 x LDG Antenna Tuner
     1 x Radio Shack HTX-242 VHF Amateur Radio

Most days I have enough solar energy to power all my devices.
However if I get several cloudy days together, the voltage can drop and my charge controllers shut down.
Then my Raspberry Pi's shut down...... And that makes me cranky.....

So I have an Arduino monitoring the battery voltage and sends that data via serial to the Raspi
If the battery voltage drops down too much due to lack of sunlight, the charger is turned on for a charge cycle (typically 6-8 hours), and then shuts off.

I plan on making quite a few of these for the many different 120VAC loads that I want to control from my Raspi.
Thanks for viewing;
Robin

Friday, December 4, 2015

Raspberry Pi & Arduino talking nicely!!!


This is a picture of success!!!
Once again many thanks have to go out to Tony DiCola of Adafruit for publishing his most AWESOME tutorial on Programming an Arduino using the Raspberry Pi GPIO
This enabled me to upgrade to Avrdude 6.1 from the Adafruit Repository and then program the Arduino thru the ICSP header from the GPIO pins.
.... And the bonus is that I can leave my serial connection from the Raspi to the Arduino connected while the programming is taking place!!!!!
So follow his steps to download the new version of Avrdude to your Raspi and hook up the pins from the GPIO header to the Arduino ICSP header.
Test run the program to ensure it can see the Arduino and you're off!
You need to directly upload a .hex file using Avrdude, so the Arduino IDE will do the converting/building for you from .ino to .hex.
I've been using Arduino-mk to upload my .ino sketches (since I like using the command line), so now I just use Arduino-mk to make the sketches, and Avrudude61 to upload them.

The following steps outline Tony's process:

Step 1 - Add the Adafruit repository to the Raspi list using the command:
curl -sLS https://apt.adafruit.com/add | sudo bash

Step 2 - Install the new version of Avrdude by running the following:
sudo apt-get install avrdude 

Step 3 - copy the /etc/avrdude.conf file to my home directory and rename it ~/avrdude_gpio.conf

Step 4 - add the following test to the end of the .conf file in my directory:

# Linux GPIO configuration for avrdude
# Change the lines below to the GPIO pins connected to the AVR. 
programmer
    id = "pi_1"; 
    desc = "Use the Linux sysfs interface to bitbang GPIO lines"; 
    type = "linuxgpio";
    reset = 12; 
    sck = 24; 
    mosi = 23; 
    miso = 18;
;

Step 5 - run the following command to confirm connection to the Arduino:
sudo avrdude -p atmega328p -C ~/avrdude_gpio.conf -c pi_1 -v

Step 6 - Once successful, goto a directory with the .hex file you want to upload to the Arduino and run the following command:
sudo avrdude -p atmega328p -C ~/avrdude_gpio.conf -c pi_1 -v -U flash:w:Blink.cpp.hex:i 
>>> and you should be able to watch Avrdude upload the sketch and verify it.

++++++++ Oh Yeah, and this is my first post done completely on my Rapsberry Pi 2 in the picture!!!! A little slower than I'm used to, but works great!!! +++++++

Sunday, November 15, 2015

Arduino & Raspberry Pi fighting


This has been my focus over the last couple of weeks (after my day job of course and the other courses I'm teaching!!!)

The top left is of course a Raspberry Pi2
To the right is an Arduino Uno clone
To the right of it is a relay board with 2 x 5VDC relays triggered from the Uno
And just above the relay board is my 12V > 5VDC power supply.

The bottom board and breadboard is a Raspi B model with a Gertduino board plugged in above it (you see 2 blue LED's lit). This is my prototyping setup for the Raspi > Uno Communications.

The Arduino powers on the left hand relay (you can just make out the Red LED) which powers on the Raspberry Pi (Raspi).
As well, the Uno monitors my battery voltage on Analogue A0 pin (batteries are not pictured).
The Raspberry Pi polls the Arduino for the Battery Voltage & if the battery voltage drops to 10.5VDC, the Raspberry Pi goes into shutdown (via a python script).
The Arduino continues to monitor the battery voltage and if it drops down to 10VDC, it shuts off the relay which powers the Raspberry Pi down safely.
Once the power is restored, the Arduino powers up and then powers up the Raspberry Pi safely.

The problem I've been struggling with though, is when the Raspberry Pi polls the Uno via the USB Cable (shown unplugged from the Uno in the picture above) the Uno resets every time which changes it's Digital output pins, which shuts down the Raspi......
Thanks to the great folks on the Arduino Forum (UKHeliBob & Robin2) I learned that when the Raspi talks to the Uno via the USB cable it includes resetting the Uno which resets the Digital pins......
What I needed to do was to talk via the 3 wire Serial (Tx, Rx, GND) between the Raspi & Uno and now no problems!!!!
You can see there is a purple and grey wire, as well as a Green/White pair  running from the Uno to the Raspi. The Green/White pair have a set of resistors to drop the Uno 5VDC down to the Raspi 3.3VDC for the Serial comms. the other wires are the ground connections (1 redundant)

So it is a bit more work, to use the USB cable to program and then switch over to the 3 wire serial for comms, but really to see it working properly is not problem at all!!!

Saturday, March 7, 2015

Update on posting to aprs.fi

Things have been quite hectic around here for the last few weeks so I haven't had a chance to post. I been asked to add some additional detail to the process I use to send my house / outdoor / & garage temperatures to aprs.fi.

I've updated my git repository (www.github.com/robingreig/raspi-git/aprx) with the latest files.
***** aprx.conf is now my configuration file with all of the custom beacon files included *****

beacon01.txt is the actual beacon file that transmits the temperatures & is beaconed every 10 minutes
T#136,22.5,38.7,15.7,0,0,00000000
T# = Telemetry
136 is my unique number (0 to a maximum of 999) each day.
***I take temperature readings every 10 minutes and save them to the file, then I take the  # of minutes since midnight for this beacon file / 4 to give me a unique number and copy that to this text file
So the unique number for my first beacon file should be 10 minutes past midnight / 4 = 2
Second unique number for the second beacon file = 20 minutes / 4 = 5
Since there are 1440 minutes in a day (24 hours x 60 minutes) / 4 my maximum beacon number would be 360 each day before it resets.
22.5 = House Temperature
37.7 = Outside Temperature + 40
*** Remembering that the number sent has to be between 0 & 255, if it is cold and I have a negative temperature, it won't send properly. So, worst case my outside temp would be -40C, so I add 40 to the outside temp so even worst case, my number would be 0. Then within my equations text file, I subtract 40 off the number to return to the actual outside temperature.
15.7 = Garage Temperatur
0,0,00000000 are additional values that are not used, but in my experience I needed to add them to the string for it to be recognized properly.

beacon02.txt is the parameters file and is beaconed every 120 minutes
:VE6RBN-1 :PARM.House Temp,Outside Temp,Garage Temp
This is a static text file that is beaconed, it does not change, since my parameters don't change

beacon03.txt is the units of measure file and is beaconed every 120 minutes
:VE6RBN-1 :UNIT.Deg C,Deg C,Deg C
This is a static text file as well and doesn't change.

beacon04.txt is the equations file and is beaconed every 120 minutes
:VE6RBN-1 :EQNS.0,1,0,0,1,-40,0,1,0
There are 3 variables sent for every parameter
House Temp (first set of 3) = 0, 1 , 0
Outside Temp (second set of 3) = 0, 1, -40
Garage Temp (third set of 3) = 0, 1, 0
First number of the set is used if we want to square the variable ( which I don't need to do)
Second number is a multiplier (I don't want to multiply my value, so I set it to 1, value x 1 = value)
Third number is a value to add to your variable.
Remembering that I added 40 to my outside temperature, here I subtract 40 from my outside variable to bring the value back to where it should be.

The only other point I wanted to bring up was that I haven't had time to experiment with sending these values out over the air, so I've set my 3 static beacon files (beacon02, beacon03, & beacon04) to be sent out over the internet only. As time allows I want to play with sending this information out over the air in a way that will be displayed properly.

Thanks for reading,
Robin

Sunday, February 8, 2015

Posting Temperature on APRS.fi

I've been working on understanding how telemetry data is sent via APRS. I found a good link on the APRS Site.

It showed me the format of the Telemetry String: T#sss,111,222,333,444,555,xxxxxxxx.

T# defines the string as a telemetry string.

They referred to the first set of numbers (sss) as the serial number and I found that it had to be a unique number from 1 - 999, each day.
I take that to mean that one could only send 999 telemetry packets over the course of the day.

The following 5 groups (111,222,333,444,555) are 5 different 3 digit, analogue values that need to be between 0 - 255.

And the final 8 are binary values which could show (open doors, devices on/off, etc)

So the first challenge I had was to determine how to setup a unique 3 digit number for each transmission, that would reset each day. I decided to go with time.
There are 24 hours x 60 minutes = 1440 minutes in a day, so that is more than 999 & won't quite work.
But I could take the total minutes of the day and divide it by 4.
Here is the Python code that I'm using:
I use the "if DEBUG > 0:" statements to print out values to help me debug a problem. Once it is working properly, I set DEBUG to 0 so they won't print during the execution of the program.

  aprs_hour = int(time.strftime("%H"))
  if DEBUG > 0:
    print "aprs_hour: ", aprs_hour
  aprs_minute = int(time.strftime("%M"))
  if DEBUG > 0:
    print "aprs_minute: ", aprs_minute
  aprs_time = int((aprs_hour * 60) + (aprs_minute)) 

The second challenge that I encountered was the outside temp.
Initially I expected to send the raw value with no problem.
February in Calgary doesn't generate positive values (grin) and so I was stuck for a bit when I saw the correct numbers being sent (-13.6 to -15.0 deg C on the day of my test) but the graph didn't move off of 0.
Then I remembered the values needed to be between 0 - 255.
Assuming the coldest temp of -40C I simply added 40 to the existing temp to bring it to a positive value and then had to figure out how to bring it back to the actual values in aprs. 

After further research, I found out about the EQNS aprs string.
Each analogue value is placed into a quadratic equation and one can send the values to modify it.
There are 3 numbers sent for each analogue value as follows:
EQNS.abc,def,ghi,jkl,mno
Since analogue value #2 is for my outside temperature, there are 3 values d, e, f that will be placed in the following equation: (Value of #2 x d2) + (Value of #2 x e) + f
So in my case of the negative outside temp, I converted it to a positive by adding 40 to it before it was sent.
My numbers for Value #2 were 0,1,-40. 0 because I didn't want to square it, 1 because I wanted the value and -40 because I had added 40 to the original value, and now needed to subtract it. 

I've setup aprx to send out these 3 fields every 120 mins:
:VE6RBN-1 :EQNS.0,1,0,0,1,-40,0,1,0
:VE6RBN-1 :UNIT.Deg C,Deg C,Deg C
:VE6RBN-1 :PARM.House Temp,Outside Temp,Garage Temp

And I've setup the temperature beacon file to be sent out every 10 minutes.
T#199,23.3,31.2,15.5,0,0,00000000
The unique number (199 above) resets at midnight every day.
You can see the telemetry graphed here: VE6RBN-1 Telemetry
And you can see the raw packets here: VE6RBN-1 Raw Packets


Sunday, January 25, 2015

Raspi & Gertduino UPS

I have purchased a couple of Arduino boards that are made specifically for the Raspberry Pi and they are named after their inventor Gert van Loo, Gertduino. The specs, software, and manual are available via this link.


It is a great platform to work on the inter-communication between the Raspi and the Arduino. I'll be using this combination to further develop my battery monitoring system for my Raspi UPS.
The Arduino will have a 3 level response:
      1)  My plan is to have my Raspi backup battery charged via the solar panels.
     2) The Arduino will monitor the battery voltage. If there is very little sun, or too much load, then the arduino can switch on the 110VAC battery charger to charge the batteries back up.
     3) The Arduino will continue to monitor the battery voltage, and if there is no sun AND no utility power, then the Arduino will safely shut down the Raspi if the voltage drops to a preset level. If the voltage continues to drop, the arduino will shut off as well.
     NOTE: The advantage of the Arduino is that it can safely recover from a power outage, where the Raspi may not. So the Arduino will power back up and when the battery voltage reaches a preset level, it will power up the Raspi.
     ARDUINO vs GERTDUINO: I like working with the Gertduino since it is mounted on the Raspi that it communicates with. However, I've been able to communicate with a regular Arduino Nano as well, so this would be the device I will use as my Battery Monitor, freeing the Raspi GPIO pins for other uses.

Wednesday, January 21, 2015

Raspi & APRX

For some reason when I completed the assembly of my RaspiTNC, I couldn't get it to run with APRX software, yet I was able to get it running on XASTIR. So I knew that my transmit and receive was working fine.... and had assumed (correctly) that I had probably made a mistake in my configuration file. I've gone back now and revisited the APRX Software page and re-read the APRX Manual. This time around I still had issues, but with the help of the APRX-Software Google Group I was able to find my configuration problem (I had left the - in my APRSIS password, so it wouldn't connect). Also I have to say that using my portable APRS setup = ASUS tablet running APRSDroid & Yaesu VX-6R & Mobilinkd TNC makes it easy to test out my iGate configurations.

Tuesday, December 23, 2014

Raspberry Pi TNC & APRS


I've finally got my RaspiTNC up and running on my Raspberry Pi. It is hard to tell from the screen, but I'm running Xastir APRS software. The APRS (Automatic Packet Reporting System) is a wonderful project led by Bob Bruninga, WB4APR, APRS. Essentially APRS is digital communications for Amateur Radio operators. Here is my home iGate station with Xastir running on the screen:


Here is a closer look at the radio and Rasperberry Pi & TNC:

The radio is showing APRS, which is the memory name for 144.390MHz, the North American APRS frequency.

A closer look at the brains of the system:

The red board is the RaspiTNC, & the green board just below is the Raspberry Pi. Just below that in the somewhat clear case is an external USB hub to power everything and below that is an 8 port switch to hook everything up. 
**** Please ignore the very, very poor job of soldering the capacitor & resistor to the 9 pin SubD connector on the RaspiTNC. This is what happens when you are in a hurry……
However I am happy to report that the TNC receives data packets via RF and transmits them to aprs.fi, and also receives packets from the internet and sends them out via RF.

You can see the APRS J-Pole antenna that I used in a post about 4 weeks ago. it is omnidirectional to provide fairly even coverage around Irricana.

If you want to see where my station is from anywhere in the world, click over to aprs.fi and track call sign VE6RBN-1 which will zoom right into my rig show here.

Monday, December 22, 2014

Raspi Block Heater Control

Well, I have a Raspberry Pi controlling a 5VDC relay, which in turn controls a 120VAC Relay which can then turn my vehicles block heater on & off. For those of you who don't live in the colder Northern climates… a block heater is an electric element that is positioned within the water jacket of your automobile engine. When the temperatures drop below -10C to -20C, the engine is cold, the engine oil is much thicker, the battery loses some of its capacity, and starting can be difficult. When we talk of plugging our cars in, we're referring to plugging the block heater in to provide heating (much like a hot water kettle) for the engine so that it will be much easier to start at those frigid temperatures. My first attempt:


You can see the Raspberry Pi in the upper left hand corner, and the 2x5VDC relays (blue) just above it.  The 5VDC relays can safely be driven from the Raspi's GPIO pins and they can safely trigger a 120VAC relay that will power the block heaters. You can see the 2 x 120VAC relays on the DIN rail just above the 3 white/grey circuit breakers. There is an advantage to using these relays (commonly known as ice cube relays, because they are about that size), and that is 1) there is an indicator light to tell me if it is powered on and 2) there is a manual lever that I can move to manually activate the relay for troubleshooting purposes. Also, if for some reason, my Raspberry Pi was not running, I could manually activate the relays to power the block heaters continuously to ensure my vehicles start in the morning. There are 2 sets of relays to power 2 different block heaters in 2 vehicles.

The only problem with the above setup is that if there is a power failure during the evening, the Raspi's SD card may become corrupted and not restart when power is applied. I find this happens on occasion and I assume it is because the SD card is being written to when the power fails.

So version 2 includes my thoughts on a UPS that I've talked about here on this blog. I've installed a power supply (upper right) and 6 x AA batteries in a holder mountain just above the Wall Adapter on the right.

Now the 12VDC wall adapter powers the power supply (small circuit board to the upper right of the DIN rail) through a 1N4007 diode. Also the 6 x AA (6 x 1.5VDC = 9VDC) batteries are tied to the power supply as well through a 1N4007 diode. Normally when the wall adapter is working, it's diode is forward biased and the power supply is supplied by the wall adapter. Should the House Power fail, the voltage will drop until it reaches 8.3VDC (9VDC from the batteries - 0.7VDC to forward bias that diode). At this point the Raspberry Pi power supply will be powered from the batteries.

Our power outages occur fairly frequently (several times a month), however they are short lived. I am hoping this battery pack will last me thru the winter…..grin.

I'm running the WebIOPi software which allows me to have the block heaters turn on and off via preset times, as well as through a webpage on my smart phone or tablet. Thanks got to Eric Ptak (trouch) who is the author of this wonderful software, WebIOPi