LowPowerLab Forum

Hardware support => General topics => Topic started by: sammythesealion on June 26, 2017, 07:55:53 PM

Title: No Observable Transmission - RFM69 w/ RadioHead Lib
Post by: sammythesealion on June 26, 2017, 07:55:53 PM
Hi all,

I'm very new to this, both the Moteino and posting, so please forgive any errors.


I've been working on a project to get a POCSAG protocol working on the Moteino-USB with a RFM69HCW. I saw a great example code here: http://www.f4huy.fr/?p=1140 It even included a POCSAG encoding library  :).

Since I haven't been able to get a hold of an RFM22 module, I've been trying to modify the code to accept the RFM69. It compiles fine, but there doesn't seem to be any transmission. The state machine is a little convoluted, but it's just parsing info based off a particular format as shown in the link above. Here's the code I've been working with: #include <SPI.h>
#include <RH_RF69.h>

// pocsag message generation library
#include <Pocsag.h>

// Singleton instance of the radio
RH_RF69 rf69;


Pocsag pocsag;

// frequency
float freq;

void setup()
{
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  Serial.begin(38400);

while (!Serial) ; // Wait for serial port to be available
 
  if (rf69.init()) {
    Serial.println("rf69 init OK");
  } else {
    Serial.println("rf69 init FAILED");
  }; // end if

  // Set frequency. AfcPullinRange set to 50 Khz (unused, we are not receiving)
  //rf69.setFrequency(433.9000, 0.00);
  rf69.setFrequency(439.9875, 0.050); // subtract 30 Khz for crystal correction
                                          // this correction-value will differ per device.
                                          // to be determined experimental

  // set to 512 bps FSK, 4.5 Khz deviation (POCSAG 1200)
  rf69.setModemConfig(RH_RF69::FSK_Rb2_4Fd4_8 );
 
  // 6 mW TX power (EU ISM legislation)
  rf69.setTxPower(14);
}

void loop() {
//vars
int rc;
int state; // state machine for CLI input

// bell = ascii 0x07
char bell=0x07;

// data
long int address;
int addresssource;
int repeat;
char textmsg[42]; // to store text message;
int msgsize;

int freqsize;
int freq1; // freq MHZ part (3 digits)
int freq2; // freq. 100 Hz part (4 digits)

// read input:
// format: "P <address> <source> <repeat> <message>"
// format: "F <freqmhz> <freq100Hz>"

Serial.println("Format:");
Serial.println("P <address> <source> <repeat> <message>");
Serial.println("F <freqmhz> <freq100Hz>");

// init var
state=0;
address=0;
addresssource=0;
msgsize=0;

freqsize=0;
freq1=0; freq2=0;

while (state >= 0) {
char c;
  // loop until we get a character from serial input
  while (!Serial.available()) {
  }; // end while

  c=Serial.read();


  // break out on ESC
  if (c == 0x1b) {
    state=-999;
    break;
  }; // end if

 
  // state machine
  if (state == 0) {
    // state 0: wait for command
    // P = PAGE
    // F = FREQUENCY
       
    if ((c == 'p') || (c == 'P')) {
      // ok, got our "p" -> go to state 1
      state=1;
     
      // echo back char
      Serial.write(c);
    } else if ((c == 'f') || (c == 'F')) {
      // ok, got our "f" -> go to state 1
      state=10;
     
      // echo back char
      Serial.write(c);
    } else {
      // error: echo "bell"
      Serial.write(bell);
    }; // end else - if

    // get next char
    continue;
  }; // end state 0

  // state 1: space (" ") or first digit of address ("0" to "9")
  if (state == 1) {
    if (c == ' ') {
      // space -> go to state 2 and get next char
      state=2;

      // echo back char
      Serial.write(c);

      // get next char
      continue;
    } else if ((c >= '0') && (c <= '9')) {
      // digit -> first digit of address. Go to state 2 and process
      state=2;

      // continue to state 2 without fetching next char
    } else {
      // error: echo "bell"
      Serial.write(bell);

      // get next char
      continue;
    }; // end else - if
  };  // end state 1

  // state 2: address ("0" to "9")
  if (state == 2) {
    if ((c >= '0') && (c <= '9')) {
      long int newaddress;

      newaddress = address * 10 + (c - '0');

      if (newaddress <= 0x1FFFFF) {
        // valid address
        address=newaddress;

        Serial.write(c);
      } else {
        // address to high. Send "beep"
        Serial.write(bell);
      }; // end else - if

    } else if (c == ' ') {
      // received space, go to next field (address source)
      Serial.write(c);
      state=3;
    } else {
      // error: echo "bell"
      Serial.write(bell);
    }; // end else - elsif - if

    // get next char
    continue;
  }; // end state 2

  // state 3: address source: one single digit from 0 to 3
  if (state == 3) {
    if ((c >= '0') && (c <= '3')) {
      addresssource= c - '0';
      Serial.write(c);

      state=4;
    } else {
      // invalid: sound bell
      Serial.write(bell);
    }; // end if

    // get next char
    continue;
  }; // end state 3


  // state 4: space between source and repeat
  if (state == 4) {
    if (c == ' ') {
      Serial.write(c);

      state=6; // go from state 4 to state 6
               // (No state 5, callsign removed)
    } else {
      // invalid: sound bell
      Serial.write(bell);
    }; // end if

    // get next char
    continue;
  }; // end state 4


  // state 5: callsign: REMOVED in non-ham version
       
  // state 6: repeat: 1-digit value between 0 and 9
  if (state == 6) {
    if ((c >= '0') && (c <= '9')) {
      Serial.write(c);
      repeat=c - '0';

      // move to next state
      state=7;
    } else {
      Serial.write(bell);
    }; // end if

    // get next char
    continue;
  }; // end state 6


  // state 7: space between repeat and message
  if (state == 7) {
    if (c == ' ') {
      Serial.write(c);

      // move to next state
      state=8;
    } else {
      // invalid char
      Serial.write(bell);
    }; // end else - if

    // get next char
    continue;
  }; // end state 7


  // state 8: message, up to 40 chars, terminate with cr (0x0d) or lf (0x0a)
  if (state == 8) {
    // accepted is everything between space (ascii 0x20) and ~ (ascii 0x7e)
    if ((c >= 0x20) && (c <= 0x7e)) {
      // accept up to 40 chars
      if (msgsize < 40) {
        Serial.write(c);

        textmsg[msgsize]=c;
        msgsize++;
      } else {
        // to long
        Serial.write(bell);
      }; // end else - if
                       
    } else if ((c == 0x0a) || (c == 0x0d) || (c == 0x2e)) {
      // done
   
      Serial.println("");
                       
      // add terminating NULL
      textmsg[msgsize]=0x00;

      // break out of loop
      state=-1;
      break;

    } else {
      // invalid char
      Serial.write(bell);
    }; // end else - elsif - if

    // get next char
    continue;
  }; // end state 8;




  // PART 2: frequency

  // state 10: space (" ") or first digit of address ("0" to "9")
  if (state == 10) {
    if (c == ' ') {
      // space -> go to state 11 and get next char
      state=11;

      // echo back char
      Serial.write(c);

      // get next char
      continue;
    } else if ((c >= '0') && (c <= '9')) {
      // digit -> first digit of address. Go to state 2 and process
      state=11;

      // init freqsize;
      freqsize=0;

      // continue to state 2 without fetching next char
    } else {
      // error: echo "bell"
      Serial.write(bell);

      // get next char
      continue;
    }; // end else - if
  };  // end state 10


  // state 11: freq. Mhz part: 3 digits needed
  if (state == 11) {
    if ((c >= '0') && (c <= '9')) {
      if (freqsize < 3) {
        freq1 *= 10;
        freq1 += (c - '0');
               
        freqsize++;
        Serial.write(c);
               
        // go to state 12 (wait for space) if 3 digits received
        if (freqsize == 3) {
          state=12;
        }; // end if
      } else {
        // too large: error
        Serial.write(bell);
      }; // end else - if
    } else {
      // unknown char: error
      Serial.write(bell);
    }; // end else - if
         
    // get next char
    continue;
         
  }; // end state 11
         

  // state 12: space between freq part 1 and freq part 2           
  if (state == 12) {
    if (c == ' ') {
      // space received, go to state 13
      state = 13;
      Serial.write(c);
               
      // reinit freqsize;
      freqsize=0;               
    } else {
      // unknown char
      Serial.write(bell);
    }; // end else - if

    // get next char
    continue;

  }; // end state 12;
               
  // state 13: part 2 of freq. (100 Hz part). 4 digits needed
  if (state == 13) {
    if ((c >= '0') && (c <= '9')) {
      if (freqsize < 4) {
        freq2 *= 10;
        freq2 += (c - '0');
               
        freqsize++;
        Serial.write(c);
      } else {
        // too large: error
        Serial.write(bell);
      }; // end else - if
           
      // get next char
      continue;
           
    } else if ((c == 0x0a) || (c == 0x0d)) {
      if (freqsize == 4) {
        // 4 digits received, done
        state = -2;
        Serial.println("");

        // break out
        break;               
      } else {
        // not yet 3 digits
        Serial.write(bell);
               
        // get next char;
        continue;
      }; // end else - if
             
    } else {
      // unknown char
      Serial.write(bell);
             
      // get next char
      continue;
    }; // end else - elsif - if

  }; // end state 12;

}; // end while


// Function "P": Send PAGE
if (state == -1) {
  Serial.print("address: ");
  Serial.println(address);

  Serial.print("addresssource: ");
  Serial.println(addresssource);

  Serial.print("repeat: ");
  Serial.println(repeat);

  Serial.print("message: ");
  Serial.println(textmsg);

  // create pocsag message
  // batch2 option = 0 (truncate message)
  // invert option1 (invert)

  rc=pocsag.CreatePocsag(address,addresssource,textmsg,0,1);


  if (!rc) {
    Serial.print("Error in createpocsag! Error: ");
    Serial.println(pocsag.GetError());

    // sleep 10 seconds
    delay(10000);
  } else {

   
    // send at least once + repeat
    for (int l=-1; l < repeat; l++) {
      Serial.println("POCSAG SEND");
      Serial.println(pocsag.GetSize());
      rf69.send((uint8_t *)pocsag.GetMsgPointer(), pocsag.GetSize());
      rf69.waitPacketSent();
     
      delay(3000);
    }; // end for

  }; // end else - if;
}; // end function P (send PAGE)

// function "F": change frequency

if (state == -2) {
  float newfreq;
 
  newfreq=((float)freq1)+((float)freq2)/10000.0F; // f1 = MHz, F2 = 100 Hz
 

  // ISM band: 434.050 to 434.800 and 863 to 870
  if ( ((newfreq >= 430.050F) && (newfreq <= 440.8F)) ||
      ((newfreq >= 863.0) && (newfreq < 870.0F)) ) {
    Serial.print("switching to new frequency: ");
    Serial.println(newfreq);
   
    freq=newfreq;

    rf69.setFrequency(freq, 0.05); // set frequency, AfcPullinRange not used (receive-only)
   
  } else {
    Serial.print("Error: invalid frequency (should be 433.050-434.800 or 853-8670 Mhz) ");
    Serial.println(newfreq);
  }; // end if
}; // end function F (frequency)



}; // end main application


The serial prints to the serial monitor work fine, but the frequency spectrum is empty. Is there something obvious I missed, like initializing pins and outputs? Or perhaps there is an easier way to go about this, perhaps the RFM69 library? Thank you all ahead of time for any help.