Old school packet radio

I’m rolling like we did it back in the 80’s. At the Boulder Amateur Radio Club BARCFest last weekend I found a later model AEA PK232MBX Terminal Node Controller (TNC) for twenty bucks.

For those of us who are wondering what the hell a TNC is and what it does, let me tell you a little story.

Way back in the day before Angry Birds and Instagraph, powerful computers were large, noisy, expensive machines that lived in air conditioned basements under large brick buildings. The kind of computers that a Ham could afford would have had kilobytes ( yes, KILObytes ) of RAM and maybe the only storage medium available was to a standard audio cassette tape. To say the least, their capability was limited.

However, communications over a serial port was one thing that nearly every home computer of the late 70’s to 80’s could do. Even the tiny Timex Sinclair 2048 could manage this feat.

This is were to the TNC steps in. A TNC is essentially a small computer running bulletin board / mail box software. On the local side it is connected via serial cable to the home computer, the remote side is connected to the audio jack of your amateur radio. The radio side of the house is generally referred to as “packet radio” or “packet bbs”.

This, kiddos, is how we rocked it back in the day. 1200 bits per second of pure text hotness (actual speeds were really in the low 100’s of bits/sec).

Replace the ham radio and TNC with a modem and telephone line and you have computer BBS’s. Replace the single BBS with the internet and you have Dialup. Replace the modem and telephone with dedicated internet and you have broadband internet.

Now get off my lawn. 73

HF/VHF/UHF Remote Operating Station

Here is my plan,  I have a 6U rack mount case already and I am planning to build a GoBox out of it.

Front:

All unpopulated rackspace is filled with blanks or vents

3U Blank Panel with cut-outs for:

  • 5″ LCD monitor w/ Raspberry Pi 3 Model B & TNC-Pi
  • 2 Front-firing Speakers (1 each for FT-450d and FT-8900r)

2U Shelf containing:

  • Yaesu FT-450d w/ Microphone and hanger
  • Yaesu FT-450d soundcard interface
  • Yaesu FT-450d PTT footswitch/headset adapter cable
  • Yaesu FT-450d PTT footswitch
  • Yaesu FT-8900r w/ Microphone and hanger
  • Yaesu FT-8900r data connection to TNC-Pi
  • Yaesu FT-8900r remote Microphone input Headset/PTT Footswitch adapter (Needed)

1U Panel with:

  • Lighted [LINE CONNECTED] LED Indicator
  • Lighted [BATT CONNECTED] LED Indicator
  • Lighted [EXT 12V CONNECTED] LED Indicator
  • Lighted [12V POWER] power switch to energize 12V power supply
  • LED voltmeter with momentary push-button switch
  • Dual Anderson PP 12V outputs
  • Powered USB 3.0 bulkhead connected to USB 3.0 HUB

Rear

2U Ventilated Panel

  • (Possible) exhaust fan with LED Switch

3U Blank Panel with:

  • Bulkhead Mains Power [MAINS IN] Fused/Switched – Common mode Chokes
  • Anderson PP [SOLAR/12V IN] – Common mode Chokes
  • Anderson PP [12V OUT] – Common mode Chokes
  • SO-239 HF Antenna – Common mode Chokes
  • SO-239 VHF/UHF Antenna – Common mode Chokes
  • SMA External GPS Antenna – Common mode Chokes

1U Ventilated Panel

Yaesu FT-450d provides

  • HF + 6M DSP 100W transceiver with ATU
  • Full CAT control and programming
  • Headset and PTT Footswitch
  • Provides HF and 6M CW/Phone/Digital/AM/FM
  • 12V supply wiring – Common mode Chokes

Yaesu FT-8900r provides

  • 10M/6M/2M FM 50W, 70cm FM 35W
  • Cross Band Full Duplex
  • Remote Programmable
  • Data connection to TNC-Pi, APRS, KISS
  • 12V supply wiring – Common mode Chokes

Powered USB 3.0 HUB provides

  • Powered from either 12V internal PS or 5V from 12V-5V DC-DC Converter
  • Connected to Front Panel jacks and Raspberry Pi
  • Allows external media and device charging

Raspberry Pi 3 Model B provides

  • Ethernet or WiFi internet connection
  • CAT programming cables for FT-450d and FT-8900r
  • CHIRP for programming radios
  • gpsd for PVT services

 

Getting useful Data from an web4robot i2c LCD into an Arduino

I got the coolest Christmas present ever, and I am finally starting to do something with it!!!

#include <LCDi2cW.h>

#include <WString.h>
#include <Wire.h>

// Doing something slightly useful with the Aduino and my web4robot i2c LCD and 4x4 keypad
// Ken Terrell

#define VERSION "1.2"

#define KEYPAD_BUTTON_1     1
#define KEYPAD_BUTTON_2     2
#define KEYPAD_BUTTON_3     3
#define KEYPAD_BUTTON_A     4
#define KEYPAD_BUTTON_4     5
#define KEYPAD_BUTTON_5     6
#define KEYPAD_BUTTON_6     7
#define KEYPAD_BUTTON_B     8
#define KEYPAD_BUTTON_7     9
#define KEYPAD_BUTTON_8     10
#define KEYPAD_BUTTON_9     11
#define KEYPAD_BUTTON_C     12
#define KEYPAD_BUTTON_STAR  13
#define KEYPAD_BUTTON_0     14
#define KEYPAD_BUTTON_POUND 15
#define KEYPAD_BUTTON_D     16

#define maxLength  8

#define BACKLIGHT  100
#define CONTRAST   50

LCDi2cW lcd = LCDi2cW(4,20,0x4C,0);             // Number of lines and i2c address of the display
 
int Backlight = 0x40;
int Contrast = 0x16;
char SecretCode[] = "1234";
String Guess = String(maxLength);
char charGuess;
int keyInput = 0;
int ledPin = 12;

void setup()
{
  Serial.begin(9600);
  Serial.print("Secret Code Box v");
  Serial.println(VERSION);
  Serial.println("");
  Serial.println("Written by Ken Terrell");
  Serial.println("");

  lcd.init();  // Init the display, clears the display
  lcd.home();
  lcd.clear();
 // delay(50);
  lcd.setBacklight(BACKLIGHT);
//  delay(50);
  lcd.setContrast(CONTRAST);
  pinMode(ledPin, OUTPUT);
  
  setkeypadmode(0);
  resetAll();
  splashscreen();
  mainscreen();
}


void loop()
{
//  charGuess = processKey(); //Get a keypress from the keypad if one is available.

Serial.print("Guess = ");
Serial.println(charGuess);
  if (processKey()) // We got one.
  {
    if (charGuess == 'A')
    { // End of Input, Check Results. Celebrate. Reset. and Redraw main screen.
      if(checkResults()) //checkResults is TRUE if you guessed the secret.
      {
        celebrate();
      }
      resetAll();
      mainscreen();
    }
    else if (Guess.length() < maxLength){
      Guess.concat(charGuess);
      lcd.setCursor(2,Guess.length());
      lcd.print("*");
    }

    while(processKey()) //Now we need to spin our wheels while until the user releases the key.
    { // do nothing in here just waiting on the user.
//       delay(400); // if we need to throttle back the i2c bus usage.
    }
  }
delay(400);
}

int checkResults() //return a 1 if correct, a 0 if incorrect.
{
  lcd.cursor_off();
  lcd.blink_off();
  lcd.clear();
  lcd.print("Your Guess was :");
  lcd.setCursor(1,0);
  lcd.print(Guess);
  lcd.setCursor(2,0);
  if (Guess.equals(SecretCode)){
    lcd.print("Congrats!");
    return(1);
  }
  else {
    lcd.print("Bummer....");
    delay(3000);
    return(0);
  }
}

void celebrate()
{
  for (int i=0; i<10; i++)
  {
    digitalWrite(ledPin, LOW);
    lcd.setBacklight(255);
    digitalWrite(ledPin, HIGH);
    lcd.setBacklight(0);
  }
}

void resetAll() //clear all strings and reset settings back to normal.
{
  Guess = NULL;
  digitalWrite(ledPin, LOW);
  lcd.setBacklight(BACKLIGHT);
  lcd.cursor_off();
  lcd.blink_off();
}  

char processKey() // read character from keypad translate to correct letter and return it.
{
  char pressed;

  int localkey;
  localkey=lcd.keypad();
  switch(localkey){
  case KEYPAD_BUTTON_1:
    pressed = '1';
    break;
  case KEYPAD_BUTTON_2:
    pressed = '2';
    break;
  case KEYPAD_BUTTON_3:
    pressed = '3';
    break;
  case KEYPAD_BUTTON_4:
    pressed = '4';
    break;
  case KEYPAD_BUTTON_5:
    pressed = '5';
    break;
  case KEYPAD_BUTTON_6:
    pressed = '6';
    break;
  case KEYPAD_BUTTON_7:
    pressed = '7';
    break;
  case KEYPAD_BUTTON_8:
    pressed = '8';
    break;
  case KEYPAD_BUTTON_9:
    pressed = '9';
    break;
  case KEYPAD_BUTTON_0:
    pressed = '0';
    break;
  case KEYPAD_BUTTON_A:
    pressed = 'A';
    break;
  case KEYPAD_BUTTON_B:
    pressed = 'B';
    break;
  case KEYPAD_BUTTON_C:
    pressed = 'C';
    break;
  case KEYPAD_BUTTON_D:
    pressed = 'D';
    break;
  case KEYPAD_BUTTON_STAR:
    pressed = '*';
    break;
  case KEYPAD_BUTTON_POUND:
    pressed = '#';
    break;
  }
  return(pressed);
}

int setkeypadmode(int keypadmode) {
//  lcd.keypadMode(keypadmode);
  delay(2);
}

void splashscreen() {
  lcd.setCursor(0,2);
  lcd.print("Keypad Ver ");             // Show Version
  lcd.print(VERSION);
  lcd.setCursor(3,0);
  lcd.print("www.bloomingfool.net");
  lcd.setCursor(1,4);
  lcd.print("Ken Terrell");
  delay(8000);
  lcd.clear();
}

void mainscreen() {
  beeper();
  lcd.clear();
  lcd.print("Enter the Secret!");
  lcd.setCursor(1,0);
  lcd.print("Then press 'A'.");
  lcd.setCursor(2,0);
  lcd.print("> ");
  lcd.cursor_on();
  lcd.blink_on();
  lcd.setCursor(2,1);
}

void beeper()
{
  digitalWrite(ledPin, HIGH);
  delay(50);
  digitalWrite(ledPin, LOW);
  delay(50);
}