Exemple #1
0
//=============================================================================
// setMode() - got to set updated transmit power level before switching to TX mode
//=============================================================================
void RFM69_ATC::setMode(uint8_t newMode) {
  if (newMode == _mode) return;
  //_powerBoost = (_transmitLevel >= 50);  // this needs to be set before changing mode just in case setHighPowerRegs is called
  RFM69::setMode(newMode);  // call base class first

  if (newMode == RF69_MODE_TX)  // special stuff if switching to TX mode
  {
    if (_targetRSSI) setPowerLevel(_transmitLevel);   // TomWS1: apply most recent transmit level if auto power
    //if (_isRFM69HW) setHighPowerRegs(true);
  }
}
/**
@author Reid Kersey <*****@*****.**> 678-736-0899

@brief This packet will keep sending data until an appropriate ACK sequence is received.

@details This packet will keep sending data until an appropriate ACK sequence is received. 
If an ACK sequence is not received after two messages are sent, the function will increase the power level.

@param device This is a sturcture of settings for the wireless device
@param packet This is the finished packetized string, formated by sendWirelessData. It could be exceptionally long.
*/
void sendWirelessPacket(struct WirelessPins *device, char* packet){
	int i;
	int response = 0;
	for(i = 0; response == 0; i++){
		if(i > 2){
			powerLevel += 1;
			setPowerLevel(device);
			i = 0;
		}
		fprintf(wirelessFile, "%s", packet);
		response = waitForResponse(device);
	}
}
Exemple #3
0
void Radio::begin(byte groupID, byte freq) {
  Serial << F("Radio. startup with unknown node number.") << endl;

  radio.initialize(freq, NODESTART, groupID);
  setNodeID(NODESTART);
  radio.setHighPower(); // using RFM69HW board
  radio.promiscuous(true); // so broadcasts are received
  setPowerLevel();
  
  Serial << F("Waiting....") << endl;
  delay( random(0,MAX_NODES)*25UL ); // wait a tick
  
  // clear rssi tracking
  for(int i=0; i<MAX_NODES; i++) {
    relRSSI[i]=1.0;
    averageRSSI[i]=CSMA_LIMIT;
  }
  
  // set up pin
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
}
/**
@author Reid Kersey <*****@*****.**> 678-736-0899

@brief This packet checks the ACK repsonse to make sure that is correct

@details This packet checks the ACK repsonse to make sure that is correct.
The ACK should be in the format of 'ACK String, lower TX level (0 is no, 1 is yes), termination string
This function checks the ACK packet for a TX level down command, and if it is received, it will lower the
power level of the device.

@note ACK_String device should receive a response like: ACK|~0|~~|$

@param device This is a sturcture of settings for the wireless device
@param ack This is the acknowlegement string received by the device
@return This function will return a 0 if the ACK is incorrect or a 1 if the ACK is correct
*/
int parseACK(char* ack, struct WirelessPins *device){
	int i;
	int changePowerLevel = 0;
	char ack_check[5] = {'A', 'C', 'K', '|', '~'};
	char term_check[3] = {'~', '|', '$'};
	for(i = 0; i < 5; i++){
		if(ack[i] != ack_check[i]){
			return 0;
		}
	}
	if(ack[5] == 1){
		changePowerLevel -= 1;
	}
	for(i = 0; i < 5; i++){
		if(ack[i+6] != term_check[i]){
			return 0;
		}
	}
	if(changePowerLevel == 1){
		powerLevel -= 1;
		setPowerLevel(device);
	}
	return 1;
}
Exemple #5
0
bool RFM69::initialize(uint32_t frequency, byte nodeID, byte networkID, byte power)
{
  const byte CONFIG[][2] =
  {
    /* 0x01 */ { REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY },
    /* 0x02 */ { REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 }, //no shaping
    /* 0x03 */ { REG_BITRATEMSB, RF_BITRATEMSB_12500}, //default:4.8 KBPS
    /* 0x04 */ { REG_BITRATELSB, RF_BITRATELSB_12500},
    /* 0x05 */ { REG_FDEVMSB, RF_FDEVMSB_5000}, //default:5khz, (FDEV + BitRate/2 <= 500Khz)
    /* 0x06 */ { REG_FDEVLSB, RF_FDEVLSB_5000},

    // /* 0x07 */ { REG_FRFMSB, (freqBand==RF69_315MHZ ? RF_FRFMSB_315 : (freqBand==RF69_433MHZ ? RF_FRFMSB_433 : (freqBand==RF69_868MHZ ? RF_FRFMSB_868 : RF_FRFMSB_915))) },
    // /* 0x08 */ { REG_FRFMID, (freqBand==RF69_315MHZ ? RF_FRFMID_315 : (freqBand==RF69_433MHZ ? RF_FRFMID_433 : (freqBand==RF69_868MHZ ? RF_FRFMID_868 : RF_FRFMID_915))) },
    // /* 0x09 */ { REG_FRFLSB, (freqBand==RF69_315MHZ ? RF_FRFLSB_315 : (freqBand==RF69_433MHZ ? RF_FRFLSB_433 : (freqBand==RF69_868MHZ ? RF_FRFLSB_868 : RF_FRFLSB_915))) },
    
    // looks like PA1 and PA2 are not implemented on RFM69W, hence the max output power is 13dBm
    // +17dBm and +20dBm are possible on RFM69HW
    // +13dBm formula: Pout=-18+OutputPower (with PA0 or PA1**)
    // +17dBm formula: Pout=-14+OutputPower (with PA1 and PA2)**
    // +20dBm formula: Pout=-11+OutputPower (with PA1 and PA2)** and high power PA settings (section 3.3.7 in datasheet)
    ///* 0x11 */ { REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | RF_PALEVEL_OUTPUTPOWER_11111},
    ///* 0x13 */ { REG_OCP, RF_OCP_ON | RF_OCP_TRIM_95 }, //over current protection (default is 95mA)
    
    ///* 0x18*/ { REG_LNA,  RF_LNA_ZIN_200 | RF_LNA_CURRENTGAIN }, //as suggested by mav here: http://lowpowerlab.com/forum/index.php/topic,296.msg1571.html
    
    // RXBW defaults are { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_5} (RxBw: 10.4khz)
    /* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_6 }, //(BitRate < 2 * RxBw)
//    /* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_2 }, //(BitRate < 2 * RxBw)
//    /* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2 }, //(BitRate < 2 * RxBw)
    /* 0x25 */ { REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 }, //DIO0 is the only IRQ we're using
    /* 0x29 */ { REG_RSSITHRESH, 220 }, //must be set to dBm = (-Sensitivity / 2) - default is 0xE4=228 so -114dBm
    ///* 0x2d */ { REG_PREAMBLELSB, RF_PREAMBLESIZE_LSB_VALUE } // default 3 preamble bytes 0xAAAAAA
    /* 0x2e */ { REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_0 },
    /* 0x2f */ { REG_SYNCVALUE1, 0x2D },      //attempt to make this compatible with sync1 byte of RFM12B lib
    /* 0x30 */ { REG_SYNCVALUE2, networkID }, //NETWORK ID
    /* 0x37 */ { REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF },
    /* 0x38 */ { REG_PAYLOADLENGTH, 66 }, //in variable length mode: the max frame size, not used in TX
    //* 0x39 */ { REG_NODEADRS, nodeID }, //turned off because we're not using address filtering
    /* 0x3C */ { REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE }, //TX on FIFO not empty
    /* 0x3d */ { REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF }, //RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent)
    /* 0x6F */ { REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 }, // run DAGC continuously in RX mode, recommended default for AfcLowBetaOn=0
    {255, 0}
  };

  pinMode(_slaveSelectPin, OUTPUT);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV2); //max speed, except on Due which can run at system clock speed
  SPI.begin();
  
  do writeReg(REG_SYNCVALUE1, 0xaa); while (readReg(REG_SYNCVALUE1) != 0xaa);
	do writeReg(REG_SYNCVALUE1, 0x55); while (readReg(REG_SYNCVALUE1) != 0x55);
  
  for (byte i = 0; CONFIG[i][0] != 255; i++)
    writeReg(CONFIG[i][0], CONFIG[i][1]);

  // Encryption is persistent between resets and can trip you up during debugging.
  // Disable it during initialization so we always start from a known state.
  encrypt(0);

  setFrequency(frequency*0.016384);
  setPowerLevel(power);
  setHighPower(_isRFM69HW); //called regardless if it's a RFM69W or RFM69HW
  setMode(RF69_MODE_STANDBY);
	while ((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady
  attachInterrupt(0, RFM69::isr0, RISING);
  
  selfPointer = this;
  _address = nodeID;
  return true;
}