Friday, 22 September 2017

LATEST Sketches and Libraries

Download.

VFO talks to PA for Band & TXRX

I have developed a way for my VFO to send data to my PA to tell it to switch bands or RX/TX mode. Both VFO & PA have a 4-way jack connection, which is connected to the Arduino UNO like this GND-pin12-pin13-+5V, +5V is on the tip.

In the VFO code is used to output a serial 9600 data transmission on pin 12 as a command to the PA. This is simply encoded 1 = 40m, 2 = 30m, 3 = 20m, 4 = Transmit, 5 = Receive. The PA receives the serial data on pin 12 and either switches the band replays of the LPFs, or changes the antenna switch from TX to RX.

CODE for both SERIAL OUT and SERIAL IN

// SERIALOUT output serial integer on TX 12
// V1.0 21-9-2017 use with SERIALIN on 2nd Arduino
// connect with Jack <-> Jack

// HEADRES & LIBRARIES
#include "SoftwareSerial.h"
#include "Oled.h"

// CONNECTIONS
// TX on 12 for VFO to send commands
#define TX 12
#define RX 13

// OBJECTS
SoftwareSerial out(RX, TX);

// GLOBAL VARIABLES
int band;

// SETUP
void setup() {
  out.begin(9600);
  while (!Serial);

  oled.begin();
}

// LOOP - test output 1,2,3,4
void loop() {
  // seq 1-3 band no. out, 4 = TX, 5 = RX
  for (band = 1; band < 7; band++) {
    out.println(band);
    dispUpdate();
    delay(2000);
  }
}

// PICTURE LOOP
// picture loop, display init data
void dispUpdate() {
  oled.firstPage();
  do {
    dispMsg(20, 20, "Band");
    dispNumL(70, 20, band, 0);
  } while ( oled.nextPage() );
}


// SERIALIN input an integer on RX 12
// V1.0 21-9-2017 use with SERIALOUT on source Arduino
// connect with Jack <-> Jack

// HEADERS & LIBRARIES
#include "SoftwareSerial.h"
#include "Oled.h"

// CONNECTIONS
// RX on 12 for PA commands, VFO sends commands on TX = 12
#define RX 12
#define TX 13


// OBJECTS
SoftwareSerial in(RX, TX);

//GLOBAL VARIABLES
int band = 1;  // 1 = 40m, 2 = 30m, 3 = 20m
bool TxRx = false; // RX

// SETUP
void setup() {
  in.begin(9600);
  while (!Serial);

  oled.begin();

  dispUpdate();
}

// LOOP
void loop() {
  if(GetBus()) {
    // change band
    // switch TXRX
  }
  dispUpdate();
}

// GETBUS
// bus input for Band or TXRX?
bool GetBus() {
  int cmd;
  
  if (in.available()) {
    if ((cmd = getInt()) != false) {
      switch (cmd) {
        case 1:        // change band
        case 2:
        case 3:
          band = cmd;
          break;
        case 4:
          TxRx = true; // TX
          break;
        case 5:
          TxRx = false;  // RX
          break;
        default:
          band = 1;
          TxRx = false;
          break;
      }
    }
    return true;
  }
  return false;
}

// GETINT
// get an integer from serial input pin RX (12)
int getInt() {

  if (in.available()) {
    return in.parseInt();
  }
  else
    return false;
}

// PICTURE LOOP
// picture loop, display init data
void dispUpdate() {
  oled.firstPage();
  do {
    dispMsgL(20, 20, "Band");
    if (band < 4)
      dispNumL(70, 20, band, 0);
    if (!TxRx)
      dispMsgL(40, 50, "RX");
    else
      dispMsgL(40, 50, "TX");
  } while ( oled.nextPage() );
}

Sunday, 10 September 2017

LATEST Sketches and libraries

Download here.

The fight to read an ASCII string into Arduino

If you have a terminal program sending characters of a string input at 9600 baud to the USB port of an Arduino, then they arrive in just over 1ms per character. In 1ms the Arduino can do a lot of things.

So a program like this won't work,

//  GET  MESSAGE
// Try to get a message in from the terminal
void getMsg(char *m) }
  int p;
  
  p = 0;
  while (Serial.available() > 0) {
   m[p++] = Serial.read();
  }
}

Why? Because after the first character arrives and Serial.Available() says it has done so, the next line Serial.read() happens very fast, a long time before the next character at 9600 baud arrives. So the next pass of the while loop fails, as there is no character in the RAM buffer.

What to do? Well wait for the next character before trying to read it, of course. Like this

// GET MESSAGE
// get line m (EOL '\n')
bool getMsg(char *m) {
  int p;

  if (Serial.available() > 0) {                 // data available ?
    p = 0;
    while ((m[p] = Serial.read()) != '\n') {    // end of line?
      p++;
      while (!Serial.available());              // wait for next char
    }
    m[p] = '\0';                                // terminate string
    return true;                                // data received
  }
  return false;                                 // no data
}

Here you can see that after the first iteration of the while loop and the Serial.read() we wait for the next character to arrive.

The next problem is to know when all the string's characters have been read, and this is done by marking the end of the input with a special character - in this case the program expects a LF or '\n'. You must make sure your terminal is set up to end the line it sends with this character.

Screen Shot 2017 09 10 at 17 13 15

Saturday, 2 September 2017

Got a new toy - USB Scope

Elektor magazine just offered me a deal I could not refuse. A SmartScope from LabNation. This is a 100ms/s sampling scope with software for PC & MacOS. Here the display of a 7.1MHz output from my VFO.

IMG 1453

Screen Shot 2017 09 02 at 14 57 14