Frequency synthesizer project

The design is based on the AD9851 chip including an atmel 328p with the Arduino bootloader. And of course I use the Arduino IDE:

IMG_1530

Top view: AD8951 with a 30 MHz oscillator, I turned the internal 6x multiplier on. There is a jumper for turning the LCD backlight on/off, perhaps I will replace this with a n-channel MOSFET switch.

IMG_1529

The rotary encoder includes a push button, the LCD lists the frequency and the increment setting.

IMG_1551

Attenuation of 30 dB is enough for direct input to the airspy/spyverter which I use as a calibrated spectum analyzer.

The design of this DDS mostly follows from the instructables website. There is a todo list for this project:

  • Find a case, right now it is half the size of a Velleman PCB.
  • Increase the output level to perhaps 5 Volt
  • Investigate whether I can turn this into a VNA

Last update: 13-dec-2017

Advertisements

Upgrade my DIY antenna tuner

The DIY antenna tuner that I described earlier in this blog showed a few shortcomings, it lacked a counter for the roller coil and the variable capacitor range was often too limited. Yesterday and today I spend time on replacing the coil with one that I got from Frans PA0FMC. I used the same capacitors and added 168 pf addons that apply to C1 and C2, so this adds two switches to the rear side. For the rest the design is still as shown below where by C1 and C2 can now vary between roughly 40 pf and 400pf.

IMG_0465

In this schematic Q is the replacement for the output antenna, and L can vary up to 24 microhenry. This is what you see on the inside, note the new location of the balun in case you want to tune an open line directly, the white switches and 4 Russian high voltage capacitors. The L, C1 and C2 must be isolated from the case, except for the base of the inductor which is connected to the case in the lower left.

diy_tuner_inside

This new frontal look:

diy_tuner_front

The G5RVj in my garden can be tuned on 80m 40m and 20m, for the 20m band I have to switch on the addon-capacitors. This DIY tuner is good for field work and the WSPR beacon, furthermore it is always good to have a second tuner in the shack. and it was fun to make it.

Last update: 2-dec-2017

MAX7219cng LED matrix controller

Playing with the MAX7219cng controlled by the Arduino

It is four years ago I did this, maybe it still works

/* code for max 7219 from maxim,
reduced and optimised for useing more then one 7219 in a row,
______________________________________

 Code History:
 --------------

The orginal code was written for the Wiring board by:
 * Nicholas Zambetti and Dave Mellis /Interaction Design Institute Ivrea /Dec 2004
 * http://www.potemkin.org/uploads/Wiring/MAX7219.txt

First modification by:
 * Marcus Hannerstig/  K3, malm� h�gskola /2006
 * http://www.xlab.se | http://arduino.berlios.de

This version is by:
 * tomek ness /FH-Potsdam / Feb 2007
 * http://design.fh-potsdam.de/ 

 * @acknowledgements: eric f. 

-----------------------------------

General notes: 

-if you are only using one max7219, then use the function maxSingle to control
 the little guy ---maxSingle(register (1-8), collum (0-255))

-if you are using more then one max7219, and they all should work the same,
then use the function maxAll ---maxAll(register (1-8), collum (0-255))

-if you are using more than one max7219 and just want to change something
at one little guy, then use the function maxOne
---maxOne(Max you wane controll (1== the first one), register (1-8),
collum (0-255))

/* During initiation, be sure to send every part to every max7219 and then
 upload it.
For example, if you have five max7219's, you have to send the scanLimit 5 times
before you load it-- other wise not every max7219 will get the data. the
function maxInUse  keeps track of this, just tell it how many max7219 you are
using.
*/
//
// For the keyboard read http://wardyprojects.blogspot.nl/2011/05/74hc165-piso-shift-register-arduino.html
// ---------------------------------------------------------------------------------------------------------------
//
//
// hardware model
//
const int dataIn = 2;      // pin 1 on the 7219
const int load   = 3;      // pin 12 on the 7219
const int clock  = 4;      // pin 13 on the 7219
const int midbutton = 5;   // mid button on matrix board
const int rightbutton = 6; // right button on matrix board
const int leftbutton = 7;  // left button on matrix board
const int maxInUse = 1;    // there is one MAX7219 in use
const int lodpin   = 10;   // purple line keyboard
const int clkpin   = 8;    // white line keyboard
const int serpin   = 9;    // green line keyboard
const int nkeys = 16;      // because there are 16 scanlines on two 74hct165 chips
char keybrd[nkeys];
char keylst[nkeys];
int keycode;
int pkeycode;
int pkeyrec;
const int maxrec = 20;
char keyrec[maxrec];
//
// max7219 registers
//
byte max7219_reg_noop        = 0x00;
byte max7219_reg_digit0      = 0x01;
byte max7219_reg_digit1      = 0x02;
byte max7219_reg_digit2      = 0x03;
byte max7219_reg_digit3      = 0x04;
byte max7219_reg_digit4      = 0x05;
byte max7219_reg_digit5      = 0x06;
byte max7219_reg_digit6      = 0x07;
byte max7219_reg_digit7      = 0x08;
byte max7219_reg_decodeMode  = 0x09;
byte max7219_reg_intensity   = 0x0a;
byte max7219_reg_scanLimit   = 0x0b;
byte max7219_reg_shutdown    = 0x0c;
byte max7219_reg_displayTest = 0x0f;
//
// global variables
//
int dt = 40;  // speed in msec in funny demos routine
int demo;
int looptime = 500;  // wait time between demos
int pbut0 = 0;
int pbut1 = 0;
int pbut2 = 0;
//int automat = 1;    // start in motion
int mindemo = 0;
int maxdemo = 10;
unsigned long int timer = 0;
unsigned long int ptimer = 0;
//unsigned long int action = 0;
unsigned long int timer0 = 0;
int state;  // what is the state of that code if it is read

//------------------------------------------------------------------------------------------

void putByte(byte data) {
  byte i = 8;
  byte mask;
  while(i > 0) {
    mask = 0x01 << (i - 1);      // get bitmask     digitalWrite( clock, LOW);   // tick     if (data & mask){            // choose bit       digitalWrite(dataIn, HIGH);// send 1     }else{       digitalWrite(dataIn, LOW); // send 0     }     digitalWrite(clock, HIGH);   // tock     --i;                         // move to lesser bit   } } //------------------------------------------------------------------------------------------ void maxSingle( byte reg, byte col)  {       //maxSingle is the "easy"  function to use for a     //single max7219   digitalWrite(load, LOW);       // begin        putByte(reg);                  // specify register   putByte(col);//((data & 0x01) * 256) + data >> 1); // put data
  digitalWrite(load, LOW);       // and load da shit
  digitalWrite(load,HIGH);
}

//------------------------------------------------------------------------------------------

void maxAll (byte reg, byte col) {    // initialize  all  MAX7219's in the system
  int c = 0;
  digitalWrite(load, LOW);  // begin
  for ( c =1; c<= maxInUse; c++) {     putByte(reg);  // specify register     putByte(col);//((data & 0x01) * 256) + data >> 1); // put data
  }
  digitalWrite(load, LOW);
  digitalWrite(load,HIGH);
}

//------------------------------------------------------------------------------------------

void maxOne(byte maxNr, byte reg, byte col) {
  //maxOne is for adressing different MAX7219's,
  //whilele having a couple of them cascaded
  int c = 0;
  digitalWrite(load, LOW);  // begin
  for ( c = maxInUse; c > maxNr; c--) {
    putByte(0);    // means no operation
    putByte(0);    // means no operation
  }
  putByte(reg);  // specify register
  putByte(col);//((data & 0x01) * 256) + data >> 1); // put data
  for ( c =maxNr-1; c >= 1; c--) {
    putByte(0);    // means no operation
    putByte(0);    // means no operation
  }
  digitalWrite(load, LOW); // and load the stuff
  digitalWrite(load,HIGH);
}

//------------------------------------------------------------------------------------------

byte flipbyte( byte input )
{
  byte output = 0;
  for (byte i=0; i<8; i++) {
    output = output << 1;     if ((input & B00000001) == B0000001) output = output | B00000001;     input = input >> 1;
  }
  return output;
}

//------------------------------------------------------------------------------------------

void Draw( int irow, int icol ) {
  byte code = 1;
  for (int j=1; j<icol; j++) code = code * 2;
  maxAll(irow,code);
}

//------------------------------------------------------------------------------------------

void UnDraw( int irow ) {
  maxAll(irow,0);
}

//------------------------------------------------------------------------------------------

void funnydemos( int choice )
{
  //
  // demo 0 just counts along rows
  //
  int row;
  int col;
  if (choice == 0) {
    for (row=1; row<=8; row++) { maxAll(row,0); }
    delay(100);
    for (col = 0; col<255; col++) {
      for (row = 1; row<=8; row++) {
        maxAll(row,col+1);
      }
      delay(5);
    }
    delay(100);
    return;
  }
  //
  // demo 1 draws rows
  //
  if (choice == 1) {
    for (row = 1; row<=8; row++) {
      maxAll(row,255);
      delay(dt);
      maxAll(row,0);
    }
    return;
  }
  //
  // demo 2 draws columns
  //
  if (choice == 2) {
    byte code = 1;
    for (col = 1; col<=8; col++) {
      for (row = 1; row<=8; row++) maxAll(row,code);
      delay(dt);
      for (row = 1; row<=8; row++) maxAll(row,0); ;
      code = code * 2;
    }
    return;
  }
  //
  // demo 3 draw a diagonals
  //
  if (choice == 3) {
    for (row=1; row<=8; row++) { maxAll(row,0); }
    delay(10);
    int ok = 0;
    int irow,icol,newrow,newcol,i;
    for (irow = 1; irow<=16; irow++) {
      for (i = -1; i<irow; i++) {         newrow = irow - i;         newcol = i;         if ((newrow >= 1) && (newrow <= 8)) {           if ((newcol >= 1) && (newcol <= 8)) {
            ok = 1;
            row = newrow;
            byte code = 1;
            for (int j=1; j<newcol; j++) code = code * 2;
            maxAll(row,code);
            //Serial.print(newrow); Serial.print(","); Serial.print(newcol); Serial.print(",");  Serial.println(code,HEX);
          }
        }
      }
      //Serial.println(" ");
      delay(dt);
      if (ok == 1) maxAll(row,0);
    }
    return;
  }
  //
  // spiraling
  //
  if (choice == 4) {
    for (row=1; row<=8; row++) { maxAll(row,0); }
    delay(10);
    int irad,irow,icol;
    int ddt = dt/2;
    for (irad = 1; irad<=4; irad++) {
      irow = irad;    for (icol = irad; icol<9-irad; icol++) { Draw(irow,icol); delay(ddt); UnDraw(irow); }
      icol = 9-irad;  for (irow = irad; irow<9-irad; irow++) { Draw(irow,icol); delay(ddt); UnDraw(irow); }       irow = 9-irad;  for (icol = 9-irad; icol>irad; icol--) { Draw(irow,icol); delay(ddt); UnDraw(irow); }
      icol = irad;    for (irow = 9-irad; irow>irad; irow--) { Draw(irow,icol); delay(ddt); UnDraw(irow); }
    }
    delay(300);
    return;
  }
  //
  // something random
  //
  if (choice == 5) {
    for (int repeat=0; repeat < 5; repeat++) {
      for (row = 1; row<=8; row++) {
        byte code = random(0,255);
        maxAll(row,code);
        delay(dt);
      }
    }
  }
  return;
}

//------------------------------------------------------------------------------------------

void DisplayMatrix(char key)
{
  switch ( key ) {
    case '0': // 0
      maxAll( 1,flipbyte(B00111110) );
      maxAll( 2,flipbyte(B00111110) );
      maxAll( 3,flipbyte(B01100011) );
      maxAll( 4,flipbyte(B01100011) );
      maxAll( 5,flipbyte(B01100011) );
      maxAll( 6,flipbyte(B01100011) );
      maxAll( 7,flipbyte(B01111111) );
      maxAll( 8,flipbyte(B00111110) );
      break;
    case '1': // 1
      maxAll( 1,flipbyte(B00001100) );
      maxAll( 2,flipbyte(B00011100) );
      maxAll( 3,flipbyte(B00011100) );
      maxAll( 4,flipbyte(B00001100) );
      maxAll( 5,flipbyte(B00001100) );
      maxAll( 6,flipbyte(B00001100) );
      maxAll( 7,flipbyte(B00001100) );
      maxAll( 8,flipbyte(B00011110) );
      break;
    case '2': // 2
      maxAll( 1,flipbyte(B00111100) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B01100110) );
      maxAll( 4,flipbyte(B00001110) );
      maxAll( 5,flipbyte(B00011100) );
      maxAll( 6,flipbyte(B00111000) );
      maxAll( 7,flipbyte(B01111110) );
      maxAll( 8,flipbyte(B01111110) );
      break;
    case '3': // 3
      maxAll( 1,flipbyte(B00111100) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B01001110) );
      maxAll( 4,flipbyte(B00011100) );
      maxAll( 5,flipbyte(B00011100) );
      maxAll( 6,flipbyte(B00001110) );
      maxAll( 7,flipbyte(B01111110) );
      maxAll( 8,flipbyte(B00111100) );
      break;
    case '4': // 4
      maxAll( 1,flipbyte(B00000110) );
      maxAll( 2,flipbyte(B00001110) );
      maxAll( 3,flipbyte(B00011110) );
      maxAll( 4,flipbyte(B00110110) );
      maxAll( 5,flipbyte(B01100110) );
      maxAll( 6,flipbyte(B01111110) );
      maxAll( 7,flipbyte(B00000110) );
      maxAll( 8,flipbyte(B00001110) );
      break;
    case '5': // 5
      maxAll( 1,flipbyte(B01111110) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B01100000) );
      maxAll( 4,flipbyte(B01111100) );
      maxAll( 5,flipbyte(B01111110) );
      maxAll( 6,flipbyte(B00000110) );
      maxAll( 7,flipbyte(B01111110) );
      maxAll( 8,flipbyte(B01111100) );
      break;
    case '6': // 6
      maxAll( 1,flipbyte(B00111100) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B01100000) );
      maxAll( 4,flipbyte(B01100000) );
      maxAll( 5,flipbyte(B01111100) );
      maxAll( 6,flipbyte(B01100110) );
      maxAll( 7,flipbyte(B01111110) );
      maxAll( 8,flipbyte(B00111100) );
      break;
    case '7': // 7
      maxAll( 1,flipbyte(B01111110) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B00000110) );
      maxAll( 4,flipbyte(B00001100) );
      maxAll( 5,flipbyte(B00011000) );
      maxAll( 6,flipbyte(B00110000) );
      maxAll( 7,flipbyte(B00110000) );
      maxAll( 8,flipbyte(B00110000) );
      break;
    case '8': // 8
      maxAll( 1,flipbyte(B00111100) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B01100110) );
      maxAll( 4,flipbyte(B01111110) );
      maxAll( 5,flipbyte(B00111100) );
      maxAll( 6,flipbyte(B01100110) );
      maxAll( 7,flipbyte(B01111110) );
      maxAll( 8,flipbyte(B00111100) );
      break;
    case '9': // 9
      maxAll( 1,flipbyte(B00111100) );
      maxAll( 2,flipbyte(B01111110) );
      maxAll( 3,flipbyte(B01100110) );
      maxAll( 4,flipbyte(B01111110) );
      maxAll( 5,flipbyte(B00111110) );
      maxAll( 6,flipbyte(B00000110) );
      maxAll( 7,flipbyte(B00111110) );
      maxAll( 8,flipbyte(B00111100) );
      break;
    case '*': // X
      maxAll( 1,B00000000 );
      maxAll( 2,B11000011 );
      maxAll( 3,B01100110 );
      maxAll( 4,B00111100 );
      maxAll( 5,B00011000 );
      maxAll( 6,B00111100 );
      maxAll( 7,B01100110 );
      maxAll( 8,B11000011 );
      break;
    case '#': // X
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B10101010) );
      maxAll( 3,flipbyte(B10101010) );
      maxAll( 4,flipbyte(B11111110) );
      maxAll( 5,flipbyte(B10101010) );
      maxAll( 6,flipbyte(B11111110) );
      maxAll( 7,flipbyte(B10101010) );
      maxAll( 8,flipbyte(B10101010) );
      break;
  }
}

//------------------------------------------------------------------------------------------

void DisplayVars( int v1, int v2 )
{
  //Serial.print(v1); Serial.print(" "); Serial.println(v2);
  int w2 = map(v2,0,1023,0,8);
  switch (w2) {
    case 0:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B00000000) );
      maxAll( 4,flipbyte(B00000000) );
      maxAll( 5,flipbyte(B00000000) );
      maxAll( 6,flipbyte(B00000000) );
      maxAll( 7,flipbyte(B00000000) );
      maxAll( 8,flipbyte(B00000000) );
      break;
    case 1:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B00000000) );
      maxAll( 4,flipbyte(B00000000) );
      maxAll( 5,flipbyte(B00000000) );
      maxAll( 6,flipbyte(B00000000) );
      maxAll( 7,flipbyte(B00000000) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 2:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B00000000) );
      maxAll( 4,flipbyte(B00000000) );
      maxAll( 5,flipbyte(B00000000) );
      maxAll( 6,flipbyte(B00000000) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 3:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B00000000) );
      maxAll( 4,flipbyte(B00000000) );
      maxAll( 5,flipbyte(B00000000) );
      maxAll( 6,flipbyte(B11111111) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 4:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B00000000) );
      maxAll( 4,flipbyte(B00000000) );
      maxAll( 5,flipbyte(B11111111) );
      maxAll( 6,flipbyte(B11111111) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 5:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B00000000) );
      maxAll( 4,flipbyte(B11111111) );
      maxAll( 5,flipbyte(B11111111) );
      maxAll( 6,flipbyte(B11111111) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 6:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B00000000) );
      maxAll( 3,flipbyte(B11111111) );
      maxAll( 4,flipbyte(B11111111) );
      maxAll( 5,flipbyte(B11111111) );
      maxAll( 6,flipbyte(B11111111) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 7:
      maxAll( 1,flipbyte(B00000000) );
      maxAll( 2,flipbyte(B11111111) );
      maxAll( 3,flipbyte(B11111111) );
      maxAll( 4,flipbyte(B11111111) );
      maxAll( 5,flipbyte(B11111111) );
      maxAll( 6,flipbyte(B11111111) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
    case 8:
      maxAll( 1,flipbyte(B11111111) );
      maxAll( 2,flipbyte(B11111111) );
      maxAll( 3,flipbyte(B11111111) );
      maxAll( 4,flipbyte(B11111111) );
      maxAll( 5,flipbyte(B11111111) );
      maxAll( 6,flipbyte(B11111111) );
      maxAll( 7,flipbyte(B11111111) );
      maxAll( 8,flipbyte(B11111111) );
      break;
  }
}

//------------------------------------------------------------------------------------------

void setup()
{
  //
  // signal the world that we are starting
  //
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  //
  // Start the serial interface
  //
  Serial.begin(115200);
  Serial.println("Keypad scanner");
  //
  // assign the pins for the max7219
  //
  pinMode(dataIn, OUTPUT);
  pinMode(clock,  OUTPUT);
  pinMode(load,   OUTPUT);
  //
  // attach the keyboard via the 74hc165 piso network
  //
  pinMode(lodpin, OUTPUT);
  pinMode(clkpin, OUTPUT);
  pinMode(serpin, INPUT);
  digitalWrite(lodpin, HIGH);
  digitalWrite(clkpin, LOW);
  //
  //initiation of the max 7219
  //
  maxAll(max7219_reg_scanLimit, 0x07);
  maxAll(max7219_reg_decodeMode, 0x00);  // using an led matrix (not digits)
  maxAll(max7219_reg_shutdown, 0x01);    // not in shutdown mode
  maxAll(max7219_reg_displayTest, 0x00); // no display test
  for (int e=1; e<=8; e++) maxAll(e,0);  // empty registers, turn all LEDs off
  maxAll(max7219_reg_intensity, 0x0f & 0x0f);    // the first 0x0f is the value you can set   // range: 0x00 to 0x0f
  for (int row=1; row<=8; row++) maxAll(row,255);
  //
  // wait a second
  //
  delay(1000);
  funnydemos(0);
  demo = 6;
  timer = millis();
  //action = 0;
  timer0 = timer;
  //automat = 1;
  pkeyrec = -1;
  //
  state = 0;
}

//------------------------------------------------------------------------------------------

void loop()
{
  timer = millis();
  //
  // scan the keyboard
  //
  digitalWrite(lodpin, LOW);
  digitalWrite(lodpin, HIGH);
  int keysum = 0;
  for ( int j=0 ; j<nkeys ; j++) {
    keybrd[nkeys - j - 1] = -1;
    int value = digitalRead(serpin);
    digitalWrite(clkpin, HIGH);
    digitalWrite(clkpin, LOW);
    keybrd[nkeys - j - 1] = value;
    keysum = keysum + value;
  }
  int keymant = 1;
  keycode = 0;
  for (int j=0; j<nkeys; j++) {
    if (keybrd[j] == 1) keycode += keymant;
    keylst[j] = keybrd[j];
    keymant = keymant << 1;   }   //Serial.println(keycode);   char key;   switch (keycode) {     case    0: key = ' '; break;     case    1: key = '*'; break;     case    2: key = '7'; break;     case    4: key = '4'; break;       case    8: key = '1'; break;     case   16: key = '0'; break;     case   32: key = '8'; break;     case   64: key = '5'; break;     case  128: key = '2'; break;     case  256: key = '#'; break;     case  512: key = '9'; break;     case 1024: key = '6'; break;      case 2048: key = '3'; break;          default:   key = '?'; break;   }   if ((keycode != pkeycode) && ((timer - ptimer) > 100)) {
    if ((key != '?') && (key != ' ')) {
      //Serial.print(key);                 // <-- if you want to debug,
      DisplayMatrix(key);
      if (pkeyrec < (maxrec-2)) {
        keyrec[++pkeyrec] = key;
      }
      if (pkeyrec == (maxrec-2)) {
        for (int k=0; k<(maxrec-3); k++) keyrec[k] = keyrec[k+1];
        keyrec[maxrec-2] = key;
      }
    }
    if (key == '#') {
      //Serial.println();                 // <-- if you want to debug
      for (int k=pkeyrec+1; k<maxrec; k++) keyrec[k] = 0;
      //Serial.println(keyrec);           // <-- if you want to debug
      pkeyrec = -1;
      //
      // check the key strings here
      //
      int fail = 1;   // whether there is a proper code
      state = -1;
      if ( strcmp(keyrec,"0#")==0 ) { state = 0; fail = 0; }   // funnydemos 0
      if ( strcmp(keyrec,"1#")==0 ) { state = 1; fail = 0; }   // funnydemos 1
      if ( strcmp(keyrec,"2#")==0 ) { state = 2; fail = 0; }   // funnydemos 2
      if ( strcmp(keyrec,"3#")==0 ) { state = 3; fail = 0; }   // funnydemos 3
      if ( strcmp(keyrec,"4#")==0 ) { state = 4; fail = 0; }   // funnydemos 4
      if ( strcmp(keyrec,"5#")==0 ) { state = 5; fail = 0; }   // funnydemos 5
      if ( strcmp(keyrec,"6#")==0 ) { state = 6; fail = 0; }   // show temperature and light
      Serial.print(keyrec); Serial.print(" -- "); Serial.println(state);
      if (fail == 0) {
        for (int kk=0; kk<strlen(keyrec); kk++) { DisplayMatrix(keyrec[kk]); delay(400); }
        if (state < 6) {
          funnydemos( state ); delay(1000);
        }
      }
    }
    pkeycode = keycode;
  }
  if (keycode != 0) ptimer = timer;
  //
  // repetitive code
  //
  if (timer < timer0) timer0 = timer;   if (timer > timer0) {
    unsigned long int delta = timer - timer0;
    if ((delta % 100) == 0) {
      // every second we arrive here
      if (state == 6) {
        int v1 = analogRead(A4); // temperature
        int v2 = analogRead(A5); // light
        DisplayVars(v1,v2);
        timer0 = timer;
      }
    }
  }
}

Last update: 27-nov-2017

Baraque Michel

Just 5 Watt is enough for reaching the PI3ZLB repeater in Geleen and the PI2NOS repeaters in Maastricht from Baraque Michel at 675m in the Ardennes. Apparently nothing is blocking the signal, QSOs are possible with an omnidirectional antenna.

Presentation1
Situation map

Last update: 19-nov-2017

Radio Caroline

Radio Caroline is back on the air at 648 kHz. They appreciate reception reports and are currently running engineering transmissions.

https://radiotoday.co.uk/2017/06/radio-caroline-allowed-1kw-tx-on-648-am/

Radio Caroline website

http://www.radiocaroline.co.uk/#home.html

Wikipedia describes all activities back to 1964, Caroline was a pirate transmitter in the 60’s, hard to receive near Geleen in the Netherlands, in the evening and during the night they are pretty loud in Rotterdam, signal to noise ratio 40 dB.

https://en.wikipedia.org/wiki/Radio_Caroline

Last update: 12-nov-2017