Thursday, 9 July 2020

Puppet training VM, Virtualbox, Mac setup and config

Youtube video tutorials
Youtube Puppet training

Puppet 6.10 VM download


Couldn't get VM to receive request on port 80/443 so did port redirect based on this article


When the VM booted the HTTP port didn't seem to show the quest guide as expected, instead it showed the nginx default boot screen "Welcome to nginx".




Edit the nginx default.conf file to set the http root directory

vi /etc/nginx/conf.d/default.conf


Modify the location section to look like this:

location / {
        root   /usr/src/puppet-quest-guide/_book;
        index  index.html index.htm;
    }

Reboot nginx

sudo systemctl restart nginx





Puppet Enterprise:
  username: admin
  password: puppetlabs

Tuesday, 12 November 2019

ESP32 with PS3 Controller - M5StickC

Arduino PS3 Library for the ESP32

Library available originally written for use with Espressif library, but it does have beta support for Arduino at the time of writing.

https://github.com/jvpernis/esp32-ps3

In my experience the device works well in both loop and callback configurations, but I did see issues when attempting to read all the available data from PS3 controller and then write to the screen. It was causing a device reboot that I wasn't able to easily solve.

How to install library:

Tested with Arduino 1.8.10 on Windows 10.

  1. From the command line, navigate to Arduino/libraries/ folder
  2. git clone https://github.com/jvpernis/esp32-ps3.git
  3. git checkout develop
  4. Restart the Arduino IDE and the library should be available in the "examples" section


How to connect to controller:

There are two ways to configure the controller with your device

  1. Retrieve the Bluetooth MAC address of the device the controller is currently connected to
  2. Set the Bluetooth MAC address of the controller
I've opted for option 1 as it allows me to keep the device connected to my PS3 for normal use. To get the PS3 controller Bluetooth MAC address follow the instructions in the readme and retrieve using the SixaxisPairTool.


M5StickC Testing

Example program showing how to retrieve all the available information from the controller and write to the M5StickC screen:

#include <M5StickC.h>
#include <Ps3Controller.h>

// M5StickC screen parameters
#define TEXT_HEIGHT 16                // Height of text to be printed and scrolled
#define TOP_FIXED_AREA 14             // Number of lines in top fixed area (lines counted from top of screen)
#define BOTTOM_FIXED_AREA 0           // Number of lines in bottom fixed area (lines counted from bottom of screen)
#define YMAX 80                       // Bottom of screen area
#define XMAX 160                      // Bottom of screen area

// M5StickC tracking drawing to screen positions
int deviceName = 0;
int controllerInfoX = 20;
int joystickInfoX = 40;
int gyroInfoX = 60;


void setup() {
  // Setup the TFT display
  M5.begin();
  M5.Lcd.setRotation(3);                               // Must be setRotation(0) for this sketch to work correctly
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLUE);
  M5.Lcd.fillRect(0, 0, XMAX, TEXT_HEIGHT, TFT_BLUE);
  M5.Lcd.drawCentreString("AliPhoenix Hexapod", XMAX/2, 0, 2);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);    // Change colour for scrolling zone text
  
  // Setup the PS3 controller
  Ps3.begin("2c:81:58:a9:8d:76");

  // Setup the serial port for debugging
  Serial.begin(115200);
  Serial.println("Ready.");
}

void loop()
{
  if (Ps3.isConnected()){
    // Clear the area we will be writing to
    M5.Lcd.fillRect(0, controllerInfoX, XMAX, TEXT_HEIGHT, TFT_BLACK);
    
    if( Ps3.data.button.cross ){ 
      M5.Lcd.drawString("Button: CROSS", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.square ){
      M5.Lcd.drawString("Button: SQUARE", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.triangle ){
      M5.Lcd.drawString("Button: TRIANGLE", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.circle ){
      M5.Lcd.drawString("Button: CIRCLE", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.left ){
      M5.Lcd.drawString("Button: LEFT", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.right ){
      M5.Lcd.drawString("Button: RIGHT", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.up ){
      M5.Lcd.drawString("Button: UP", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.down ){
      M5.Lcd.drawString("Button: DOWN", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.l1 ){
      M5.Lcd.drawString("Button: L1", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.l2 ){
      M5.Lcd.drawString("Button: L2", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.l3 ){
      M5.Lcd.drawString("Button: L3", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.r1 ){
      M5.Lcd.drawString("Button: R1", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.r2 ){
      M5.Lcd.drawString("Button: R2", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.r3 ){
      M5.Lcd.drawString("Button: R3", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.start ){
      M5.Lcd.drawString("Button: START", 0, controllerInfoX, 2);
    }
    if( Ps3.data.button.select ){
      M5.Lcd.drawString("Button: SELECT", 0, controllerInfoX, 2);
    }
  //-----------------------------------------------------------------------
    // Clear the area we will be writing to
    M5.Lcd.fillRect(0, joystickInfoX, XMAX, TEXT_HEIGHT, TFT_BLACK);
    
    String messageJoystick;
    
    messageJoystick += "lx:";
    messageJoystick += Ps3.data.analog.stick.lx;
    messageJoystick += ", ly:";
    messageJoystick += Ps3.data.analog.stick.ly;
    messageJoystick += ", rx:";
    messageJoystick += Ps3.data.analog.stick.rx;
    messageJoystick += ", ry:";
    messageJoystick += Ps3.data.analog.stick.ry;
    
    // Write the message to the screen
    M5.Lcd.drawString(messageJoystick, 0, joystickInfoX, 2);
  //-----------------------------------------------------------------------
    String message = "PS3: Connected";
  
    // Clear the area we will be writing to
    M5.Lcd.fillRect(0, deviceName, XMAX, TEXT_HEIGHT, TFT_BLACK);
    
    if (Ps3.data.status.battery == ps3_status_battery_charging) message += ", Charging";
    else if (Ps3.data.status.battery == ps3_status_battery_high) message += ", High";
    else if (Ps3.data.status.battery == ps3_status_battery_full) message += ", Full";
    else if (Ps3.data.status.battery == ps3_status_battery_low) message += ", Low";
    else if (Ps3.data.status.battery == ps3_status_battery_dying) message += ", Dying";
    else if (Ps3.data.status.battery == ps3_status_battery_shutdown) message += ", Shutdown";
    else message += ", Undefined";
  
    // Write the message to the screen
    M5.Lcd.drawString(message, 0, deviceName, 2);
  //-----------------------------------------------------------------------
    String messageAccel;
    
    messageAccel += "a.x:";
    messageAccel += Ps3.data.sensor.accelerometer.x;
    messageAccel += " y:";
    messageAccel += Ps3.data.sensor.accelerometer.y;
    messageAccel += " z:";
    messageAccel += Ps3.data.sensor.accelerometer.z;
  
    String messageGyro;
    messageGyro += " g.z:";
    messageGyro += Ps3.data.sensor.gyroscope.z;
  
    M5.Lcd.drawString(messageAccel+messageGyro, 0, gyroInfoX, 2);
  }
  
  delay(100);
}

Monday, 9 September 2019

ARDUINO: ESP32 Bluetooth Serial Pass-through And Debugger - M5StickC

This is a simple Arduino project showing how to use the M5StickC device as a bluetooth/serial port pass through with the LCD screen as a built in debugger.

The device shows up on your phone as a bluetooth device called "M5StickC", and once you've connected from your device you can use an app like Serial Bluetooth Terminal communicate with your device.

Messages coming from USB serial port are printed as white text and messages coming from bluetooth are printed as blue text.



#include "bluetoothserial.h"
#include "m5stickc.h"

// M5StickC screen parameters
#define TEXT_HEIGHT 16                    // Height of text to be printed and scrolled
#define TOP_FIXED_AREA 14             // Number of lines in top fixed area (lines counted from top of screen)
#define BOTTOM_FIXED_AREA 0       // Number of lines in bottom fixed area (lines counted from bottom of screen)
#define YMAX 80                                  // Bottom of screen area
#define XMAX 160                                // Bottom of screen area

uint16_t  yStart = 0;                               // The initial y coordinate of the top of the scrolling area
uint16_t  yArea = YMAX-TOP_FIXED_AREA-BOTTOM_FIXED_AREA; // yArea must be a integral multiple of TEXT_HEIGHT
uint16_t  yDraw = 0;                              // The initial y coordinate of the top of the bottom text line
uint16_t  xPos = 0;                                // Keep track of the drawing x coordinate
byte      data = 0;
int       blank[19];                                    // We keep all the strings pixel lengths to optimise the speed of the top line blanking


BluetoothSerial SerialBT;


void setup() {
  // Setup the TFT display
  M5.begin();
  M5.Lcd.setRotation(3);                               // Must be setRotation(0) for this sketch to work correctly
  M5.Lcd.fillScreen(TFT_BLACK);

  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLUE);
  M5.Lcd.fillRect(0, 0, XMAX, TEXT_HEIGHT, TFT_BLUE);
  M5.Lcd.drawCentreString("Serial Term - 115200", XMAX/2, 0, 2);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);    // Change colour for scrolling zone text

  setupScrollArea(TOP_FIXED_AREA, BOTTOM_FIXED_AREA); // Setup scroll area
  for (byte i = 0; i<18; i++) blank[i]=0;            // Zero the array

  Serial.begin(115200);                                 // Initialise the serial ports
  SerialBT.begin("M5StickC");                       // Bluetooth device name
  Serial.println("\n# Bluetooth started #\n");  // Let the user know via usb serial port the device is ready
}

void loop() {
  // Check the Serial buffer for a new message
  while(Serial.available()) {
    data = Serial.read();                                 // Read the character from the serial port
    SerialBT.write(data);                                 // Write the message to the Bluetooth serial port
    M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK); 
    writeToScreen(data);                                // Also write to the M5StickC screen
  }

  // Check the bluetooth buffer for a new message
  while(SerialBT.available()) {
    data = SerialBT.read();                             // Read the character from the bluetooth port
    Serial.write(data);                                     // Write the message to the serial port
    M5.Lcd.setTextColor(TFT_BLUE, TFT_BLACK); 
    writeToScreen(data);                                // Also write to the M5StickC screen
  }
  
  delay(20);
}

void writeToScreen(byte data) {
  // If it is a CR or we are near end of line then scroll one line
  if (data == '\r' || xPos > XMAX) {
    xPos = 0;
    yDraw = scroll_line();                                // It can take 13ms to scroll and blank 16 pixel lines
  }
  
  if (data > 31 && data < 128) {
    xPos += M5.Lcd.drawChar(data,xPos,yDraw,2);
  }
}

/**
 * Scroll the display one text line
 */
int scroll_line() {
  // Store the old yStart, this is where we draw the next line
  int yTemp = yStart;
  
  // Use the record of line lengths to optimise the rectangle size we need to erase the top line
  M5.Lcd.fillRect(0,yStart,XMAX,TEXT_HEIGHT,TFT_BLACK);

  // Change the top of the scroll area
  yStart += TEXT_HEIGHT;

  // The value must wrap around as the screen memory is a circular buffer
  if (yStart >= YMAX)
    yStart = 0;

  // Now we can scroll the display
  scrollAddress(yStart);

  return  yTemp;
}

/**
 * Setup the vertical scrolling start address pointer
 */
void scrollAddress(uint16_t vsp) {
  M5.Lcd.writecommand(ST7735_VSCRDEF);  // Vertical scrolling pointer
  M5.Lcd.writedata(vsp>>8);
  M5.Lcd.writedata(vsp);
}

/**
 * Setup a portion of the screen for vertical scrolling
 * We are using a hardware feature of the display, so we can only scroll in portrait orientation
 */
void setupScrollArea(uint16_t tfa, uint16_t bfa) {
  M5.Lcd.writecommand(ST7735_VSCRDEF);  // Vertical scroll definition
  M5.Lcd.writedata(tfa >> 8);                               // Top Fixed Area line count
  M5.Lcd.writedata(tfa);
  M5.Lcd.writedata((YMAX-tfa-bfa)>>8);             // Vertical Scrolling Area line count
  M5.Lcd.writedata(YMAX-tfa-bfa);
  M5.Lcd.writedata(bfa >> 8);                              // Bottom Fixed Area line count
  M5.Lcd.writedata(bfa);
}

Monday, 22 July 2019

Visual Studio Code with Arduino - ESP8266

The Arduino IDE is awesome for getting small projects up and running really quickly, but as soon as your project starts to get a little more complex and you are creating and managing more than a handful of files it gets painful pretty quickly.

Visual Studio Code is an alternative IDE you can use not only to edit your projects, but also build, upload and even debug your project! It comes with benefits like Intellisense, Git integration and easy navigation to definitions.

I followed this guide to get started, but there were a few little things that tripped me up I thought I'd give some more detailed examples.

1. Get yourself setup with Visual Studio Code

Download and install VS Code for your OS. I'm using a Mac for this, I haven't tried with Windows/Linux but process should be the same.


2. Install the Arduino plugin

Install the VS Code plugin for Arduino from the VS code store. Take note of the recommended version of Arduino to install (required for Step 3).



3. Install the Arduino IDE

VS Code will use the Arduino to actually build your project. Take note of the Arduino version comment in the VS code arduino plugin and select an appropriate version to download.

4. Open your project

Use the file->open (not "open workspace") to open the root folder of your project.

5. Configure your settings

Add any special boards you want to the project config. In my case I've added the esp8266 boards.
Menu -> Code -> Preferences -> Workspace Preferences Tab -> Type "additionalUrls" in the search bar and "Edit in settings.json" the file.


Add the following so your settings.json file looks something like this:

{
"arduino.enableUSBDetection": false,
"arduino.additionalUrls":"http://arduino.esp8266.com/stable/package_esp8266com_index.json"
}

6. Set your Arduino board

Set the board for your project either from the drop down menu at the bottom of the screen or by navigating to the command options using cmd + shift + p, then searching for "Arduino" commands and select the "Arduino: Change Board Type". 
It can take a while for this to load sometimes, be patient. It took around a minute the first time I opened it for my project. Sometimes my board configuration screen is black as I've shown below


7. Initialise the project

Ctrl+Shift+P and then search for "Arduino" commands, scroll down to "Initialise" and hit it. This will add a arduino.json and c_cpp_properties.json files to your project and set up a few things. Add any project dependencies here.

8. Compile your code

Compile with the shortcut Command+Option+r, or by searching for the Arduino compile option with Ctrl+Shift+P.
You will see the Arduino logo pop up during the compilation step.

9. Upload your code

Upload with Command+Option+U

Troubleshooting

Its worth calling out that Arduino doesn't behave as you would expect with included files/folders.
Even though the VS Code IDE will be able to find a file/folder because you have linked it there is a chance it still may not compile.

Take a read through the expected Arduino project file structure here and organise your project to suit.

Thursday, 8 March 2018

Resetting an SD card after writing a Linux Image from Windows

After writing the Rasbian image to my SD card for a new Raspberry Pi project I found myself wanting to reset the SD card to be used as normal storage so I could install NOOBS, but I got stuck when I couldn't work out how to delete the partitions made by writing the image on the device from Windows.

I found a Windows solution in the way of DISKPART that got the job done.

How to use DISKPART


  1. Open a new command window by either searching for "cmd" from the windows menu or pressing the windows key and 'r' and running the command "cmd" and hit enter
  2. Enter the command "DISKPART" and another command window will be opened
  3. In the new window type "LIST DISK" and hit enter
  4. Select the correct disk from the list with the command "SELECT DISK #" replacing the # with the drive number of the SD card. Make sure you get this right or you could ruin your windows installation!
  5. Enter the command "CLEAN" to clear the partition table
  6. Enter the command "CREATE PARTITION PRIMARY" to reallocate the cleaned space as the primary partition
  7. Enter the command "FORMAT FS=FAT32 QUICK" to reformat the SD card

Optionally you can use the command "ASSIGN" to reassign a drive letter to the SD card.

Sunday, 2 July 2017

DRONE: Ublox Neo M8N GPS + SP Racing F3 Wiring

I have been toying with adding GPS to my quadcopter and after doing some research I went ahead and purchased the Mini Ublox M8N Neo GPS Receiver from banggood.

The banggood site has a few different options for different flight controllers, but the SP racing version doesn't come with a compass. I have the Eachine version of the SP racing board that didn't come with a compass, barometer or altimeter so I bought the APM version and decided I would replace the connectors to suit my board.

The SP Racing F3 manual says that the connectors are JST-XH but I ordered a few and was disappointed to discover they were the wrong ones for my Eachine version of the SP racing board.
After ordering a few types, I discovered the type on my board are the JST-SH 1.0mm (at least for the 4 pin ports).

I found out the hard way that the little piece of paper that comes with the device is misleading.
I was expecting that I would need to cross TX/RX from the GPS device when connecting to the FC, so I wired based on that and got stuck for a while trying to work out why my device wouldn't connect to my FC. It took me a while to realise that I should have been following the diagram below from the banggood website.


Once I fixed this the device connected immediately and functioned as expected. By default my device was working at 9600 baud.