Exemplo n.º 1
0
//--------------------------------------------------------------------------------------------------
// Send payload data via RF
//-------------------------------------------------------------------------------------------------
void tools_rfwrite (byte myNodeID, const void* ptr, uint8_t len) {
   if(tools_ack()){
      for (byte i = 0; i <= RETRY_LIMIT; ++i) {  // tx and wait for ack up to RETRY_LIMIT times
        rf12_sleep(-1);              // Wake up RF module
         while (!rf12_canSend())
         rf12_recvDone();
         rf12_sendStart(RF12_HDR_ACK, ptr, len); 
         rf12_sendWait(2);           // Wait for RF to finish sending while in standby mode
         byte acked = waitForAck(myNodeID);  // Wait for ACK
         rf12_sleep(0);              // Put RF module to sleep
         if (acked) { return; }      // Return if ACK received
     
         Sleepy::loseSomeTime(RETRY_PERIOD * 1000);     // If no ack received wait and try again
      }
   }
   else {
      rf12_sleep(-1);              // Wake up RF module
      while (!rf12_canSend())
         rf12_recvDone();
      rf12_sendStart(0, ptr, len); 
      rf12_sendWait(2);           // Wait for RF to finish sending while in standby mode
      rf12_sleep(0);              // Put RF module to sleep
      return;
   }
}
Exemplo n.º 2
0
void forwardPacket() {
    // make copies, because rf12_* will change in next rf12_recvDone
    byte hdr = rf12_hdr, len = rf12_len;
    if (config.multi_node) {
        // special case: insert original header (src node ID) as first data byte
        // careful with max-length packets in multi-node mode: drop last byte!
        // this is necessary because we're inserting an extra byte at the front
        if (len >= sizeof buf)
            --len;
        buf[0]= hdr;
    }
    memcpy(buf + config.multi_node, (void*) rf12_data, len);

    // save these for later as well, same reason as above
    byte wantsAck = RF12_WANTS_ACK, ackReply = RF12_ACK_REPLY;
    if (config.acks_enable) {
        // if we're not supposed to send back ACKs, then don't ask for 'em
        wantsAck = false;
        hdr &= ~ RF12_HDR_ACK;
    }

    Serial.print("\n[*]");

    // switch to outgoing group
    rf12_initialize(config.out_node, code2type(config.freq), config.out_group);

    // send our packet, once possible
    while (!rf12_canSend())
        rf12_recvDone();
    rf12_sendStart(hdr, buf, len + config.multi_node, 1);

    if (wantsAck) {
        ackTimer.set(100); // wait up to 100 ms for a valid ack packet
        wantsAck = false;
        while (!wantsAck && !ackTimer.poll())
            wantsAck = rf12_recvDone() && rf12_crc == 0;
    }

    // switch back to incoming group
    rf12_initialize(config.in_node, code2type(config.freq), config.in_group);

    if (wantsAck) {
        // copy ack packet to our temp buffer, same reason as above
        len = rf12_len;
        memcpy(buf, (void*) rf12_data, rf12_len);

        // send ACK packet back, once possible
        while (!rf12_canSend())
            rf12_recvDone();
        rf12_sendStart(ackReply, buf, len, 1);
    }
}
Exemplo n.º 3
0
void OpenGardenClass::receiveFromNode(void){

  if (rf12_recvDone() && rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) {
    nodeID = rf12_hdr & 0x1F;  // get node ID
    airPacket = *(Payload*) rf12_data;


    if (RF12_WANTS_ACK) {           // Send ACK if requested
      rf12_sendStart(RF12_ACK_REPLY, 0, 0);
    }
  }
  //Receive data and store the last value in buffer
  if (nodeID == 1) 
    nodesBuffer[0] = airPacket; //Node:1->Buffer:0
  else if (nodeID == 2) 
    nodesBuffer[1] = airPacket; //Node:2->Buffer:1
  else if (nodeID == 3) 
    nodesBuffer[2] = airPacket; //Node:3->Buffer:2
  else if (nodeID == 4) 
    nodesBuffer[3] = airPacket; //Node:4->Buffer:3
  else if (nodeID == 5) 
    nodesBuffer[4] = airPacket; //Node:5->Buffer:4
  else if (nodeID == 6) 
    nodesBuffer[5] = airPacket; //Node:6->Buffer:5
  else if (nodeID == 7) 
    nodesBuffer[6] = airPacket; //Node:7->Buffer:6
}
Exemplo n.º 4
0
void OpenGardenClass::debugRF(void){

  if (rf12_recvDone() && rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) {
    nodeID = rf12_hdr & 0x1F;  // get node ID
    airPacket = *(Payload*) rf12_data;

    Serial.print("Received packet from node ");
    Serial.println(nodeID);
    Serial.print("Temperature:");
    Serial.print(airPacket.temperature);
    Serial.println("*C");
    Serial.print("Humidity:");
    Serial.print(airPacket.humidity);
    Serial.println("%RH");
    Serial.print("Soil Moisture:");
    Serial.println(airPacket.moisture);
    Serial.print("Luminosity:");
    Serial.println(airPacket.light);
    Serial.print("Battery Voltage:");
    Serial.print(airPacket.supplyV);
    Serial.println("mV");
    Serial.println("***************");

    if (RF12_WANTS_ACK) {           // Send ACK if requested
      rf12_sendStart(RF12_ACK_REPLY, 0, 0);
    }
  }
}
Exemplo n.º 5
0
boolean AQERF_Base::pair(){
    uint32_t current_time = millis();
    boolean pairing_done = false;
    
    if (rf12_recvDone()) {   // incoming data is present
        if(0 == rf12_crc){   // otherwise the data is unreliable                    
            if(pairingRxCallback != 0){
                pairingRxCallback(packet);
            }
        }
    }    
    
    if(current_time < end_time){       
        if(current_time - previous_time > PAIRING_BROADCAST_INTERVAL_MS) {
            previous_time = current_time; 
            need_to_send = 1;
        }

        if(need_to_send && rf12_canSend()){
            rf12_sendStart(0, packet, AQERF_BASE_STATION_ADVERTISEMENT_PACKET_LENGTH);
            need_to_send = 0;
        }

        pairing_done = false;
    }       
    else{
        pairing_done = true;
    }

    return pairing_done;
}
Exemplo n.º 6
0
/// @details
/// Needs to be called often to keep the easy transmission mechanism going,
/// i.e. once per millisecond or more in normal use. Failure to poll frequently
/// enough is relatively harmless but may lead to lost acknowledgements.
/// @returns 1 = an ack has been received with actual data in it, use rf12len
///          and rf12data to access it. 0 = there is nothing to do, the last
///          send has been ack'ed or more than 8 re-transmits have failed.
///          -1 = still sending or waiting for an ack to come in
/// @note To be used in combination with rf12_easyInit() and rf12_easySend().
char rf12_easyPoll () {
    if (rf12_recvDone() && rf12_crc == 0) {
        byte myAddr = nodeid & RF12_HDR_MASK;
        if (rf12_hdr == (RF12_HDR_CTL | RF12_HDR_DST | myAddr)) {
            ezPending = 0;
            ezNextSend[0] = 0; // flags succesful packet send
            if (rf12_len > 0)
                return 1;
        }
    }
    if (ezPending > 0) {
        // new data sends should not happen less than ezInterval seconds apart
        // ... whereas retries should not happen less than RETRY_MS apart
        byte newData = ezPending == RETRIES;
        long now = millis();
        if (now >= ezNextSend[newData] && rf12_canSend()) {
            ezNextSend[0] = now + RETRY_MS;
            // must send new data packets at least ezInterval seconds apart
            // ezInterval == 0 is a special case:
            //      for the 868 MHz band: enforce 1% max bandwidth constraint
            //      for other bands: use 100 msec, i.e. max 10 packets/second
            if (newData)
                ezNextSend[1] = now +
                                (ezInterval > 0 ? 1000L * ezInterval
                                 : (nodeid >> 6) == RF12_868MHZ ?
                                 13 * (ezSendLen + 10) : 100);
            rf12_sendStart(RF12_HDR_ACK, ezSendBuf, ezSendLen);
            --ezPending;
        }
Exemplo n.º 7
0
void trace_flush(bool force=false) {
  if (force && trace_cnt > 0 || trace_cnt >= TRACE/2) {
    if (rf12_canSend()) {
      trace_buf[0] = LOG_MODULE;
      rf12_sendStart(node_id, trace_buf, trace_cnt+1);
      trace_cnt = 0;
    }
  }
}
Exemplo n.º 8
0
uint8_t AQERF_Remote::pair(){
    // try this for a period of time up to the pairing duration
    uint8_t return_value = 0;
    uint8_t rx_base_station_address[6];   
    uint8_t comparison = 0; 
    eeprom_read_block(base_station_address, (const void *) AQERF_EEPROM_LAST_KNOWN_BASE_ADDRESS, 6);
    for(uint32_t ii = 0; ii < AQERF_PAIRING_DURATION_MS; ii++){
        if (rf12_recvDone()) {   // incoming data is present
            if(0 == rf12_crc){   // otherwise the data is unreliable
                if(AQERF_PACKET_TYPE_BASE_STATION_ADVERTISEMENT == rf12_data[AQERF_PACKET_TYPE_OFFSET]){
                    // we have a pairing ... 
                    //   store the advertised base address in RAM and EEPROM
                    memcpy(rx_base_station_address, (const void *) (rf12_data + AQERF_BASE_ADDRESS_OFFSET), AQERF_BASE_ADDRESS_LENGTH);
                    
                    // ping back to the base to let it know you are all set by echoing the packet with your address
                    memcpy(packet + AQERF_BASE_ADDRESS_OFFSET, unit_address, AQERF_BASE_ADDRESS_LENGTH);

                    delay(200);
                    
                    while(!rf12_canSend()){
                      rf12_recvDone();
                    }
                    
                    rf12_sendStart(0, packet, AQERF_BASE_STATION_ADVERTISEMENT_PACKET_LENGTH);
                    
                    //for(uint8_t jj = 0; jj < 100; jj++){
                    //  rf12_recvDone();  // ensures the packet gets sent                  
                    //}     
                    
                    Serial.println(F("Sent ACK"));
                    
                    //Store the base_station_address to EEPROM         
                    comparison = 1;
                    for(uint8_t jj = 0; jj < 6; jj++){
                      if(rx_base_station_address[jj] != base_station_address[jj]){
                        comparison = 0;
                      }
                    }   
                    
                    if(comparison == 0){     
                      Serial.println(F("Overwriting EEPROM"));
                      eeprom_write_block(rx_base_station_address, (void *) AQERF_EEPROM_LAST_KNOWN_BASE_ADDRESS, 6);
                      eeprom_read_block(base_station_address, (const void *) AQERF_EEPROM_LAST_KNOWN_BASE_ADDRESS, 6);                      
                    }
                     
                    return_value = 1;
                }
            }
        }
        delay(1);
    }
    
    return return_value;
}
Exemplo n.º 9
0
void loop() {
  for (int i = 0; i < NUM_COUNTERS; i++) { // loop through the counters
    // read the counter input pin:
    counterState[i] = digitalRead(counterPin[i]);

    // compare the counterState to its previous state
    if (counterState[i] != lastCounterState[i]) {
      if (counterState[i] == LOW) {
        digitalWrite(LED1, HIGH);
        // if the current state is HIGH then the button
        // wend from off to on:
#ifdef DEBUG_ENABLED
        Serial.print(i);
        Serial.println(" LOW");
#endif

				payload.active_counter = i;
				counterMillis[i] = millis();
				payload.counter_millis = counterMillis[i];
 
        if (counterMillis[i] - lastCounterMillis[i] > 90) {
				// send a packet
				while (!rf12_canSend()) 
					rf12_recvDone();

				// send as broadcast, payload will be encrypted
				rf12_sendStart(0, &payload, sizeof(payload));
				rf12_sendWait(1);
        }
        lastCounterMillis[i] = counterMillis[i];
#ifdef DEBUG_ENABLED
      } else {
        // transision from LOW to HIGH means the pulse is over
        // we're not interested in that
        Serial.print(i);
        Serial.println(" HIGH"); 
#endif
      }
      Serial.println();
    }
    // save the current state as the last state, 
    //for next time through the loop
    lastCounterState[i] = counterState[i];

    if (led1Timer.poll(90)) {
      digitalWrite(LED1, LOW);
    }
  }
  wdt_reset();
  
}
Exemplo n.º 10
0
bool RF12Module::Send(byte destination, byte* message, uint8_t sendLen,
		bool needAck) {
	if (rf12_canSend()) {
		byte header = needAck ? RF12_HDR_ACK : 0;
		if (destination)
			header |= RF12_HDR_DST | destination;
		rf12_sendStart(header, message, sendLen);
		rf12_sendWait(1);
		return true;
	} else {
		// What must we do...
		return false;
	}
}
Exemplo n.º 11
0
// send the packet at the top of the queue
void Net::doSend(void) {
#ifdef NET_NONE
  return;
#else
  if (bufCnt > 0) {
    uint8_t hdr = buf[0].hdr;
    // Don't ask for an ACK on the last retry
    if (sendCnt+1 >= NET_RETRY_MAX)
      hdr &= ~RF12_HDR_ACK;
    // send as broadcast packet without ACK
#ifdef NET_RF12B
    rf12_sendStart(hdr, &buf[0].data, buf[0].len);
    trace('S');
#else
#ifdef NET_SERIAL
#endif
#endif

#if DEBUG
    Serial.print(F("Net::doSend: "));
    Serial.print(hdr & RF12_HDR_ACK ? "  w/ACK " : " no-ACK ");
    Serial.print("#");
    Serial.print(sendCnt);
    Serial.print(" 0x");
    Serial.print(buf[0].data[0], 16);
    Serial.print(":"); Serial.println(buf[0].len);
#endif
    // pop packet from queue if we don't expect an ACK
    if ((hdr & RF12_HDR_ACK) == 0) {
      if (bufCnt > 1)
        memcpy(buf, &buf[1], sizeof(net_packet)*(NET_PKT-1));
      bufCnt--;
      sendCnt=0;
    } else {
      sendCnt++;
      sendTime = millis();
    }
    trace('0'+bufCnt);
  }
#endif
}
Exemplo n.º 12
0
boolean AQERF_Base::pair(void){
    uint32_t current_time = millis();
    boolean pairing_done = false;
    if(current_time < end_time){
        rf12_recvDone();
        if(current_time - previous_time > PAIRING_BROADCAST_INTERVAL_MS) {
            previous_time = current_time; 
            need_to_send = 1;
        }

        if(rf12_canSend() && need_to_send){
            rf12_sendStart(0, packet, AQERF_BASE_STATION_ADVERTISEMENT_PACKET_LENGTH);
            need_to_send = 0;
        }

        pairing_done = false;
    }       
    else{
        pairing_done = true;
    }

    return pairing_done;
}
Exemplo n.º 13
0
void sendTempPacket() {
    digitalWrite(PIN_LED, HIGH);
#define N 512
#define PIN_TEMP1 2
#define PIN_TEMP2 3
    long t1 = 0;
    long t2 = 0;
    Serial.print("[");
    for (int i = 0; i < N; i++) {
        if (rf12_recvDone() && rf12_crc == 0) {
            forwardPacket();
        }
        t1 += analogRead(PIN_TEMP1);
        t2 += analogRead(PIN_TEMP2);
    }
    Serial.print(t1 / N * 3300 / 1024);
    Serial.print(" ");
    Serial.print(t2 / N * 3300 / 1024);
    Serial.print(" ");
    //long t = ((l2 - l1) * 3300) / 4096;
    long t = (t2 - t1) * 3300 * 10 / N / 1024;
    Serial.print(t);

    rf12_initialize(config.out_node, code2type(config.freq), config.out_group);
    Serial.print(" *");

    payload[4] = 1;
    *((int*)(payload + 5)) = (int) t;

    // send our packet, once possible
    while (!rf12_canSend())
        rf12_recvDone();
    Serial.print(" *");
    rf12_sendStart(0, payload, sizeof payload, 1);
    Serial.println("]");
    digitalWrite(PIN_LED, LOW);
}
Exemplo n.º 14
0
void sendPulsePacket() {
	cli();
	volatile unsigned long long pulsesNow = pulses;
	volatile unsigned long noiseNow = noise;
	sei();
	Serial.print("(");
	Serial.print(millis());
	Serial.print(")");
    digitalWrite(PIN_LED, HIGH);
	Serial.print("[P:");
	Serial.print((unsigned long)pulsesNow);
	Serial.print(",");
	Serial.print(noise);
	pulsePayload[4] = 4;
	*((unsigned long long*)(pulsePayload + 5)) = pulsesNow;
	*((unsigned long*)(pulsePayload + 13)) = noiseNow;
    // send our packet, once possible
    while (!rf12_canSend())
        rf12_recvDone();
    Serial.print(" *");
    rf12_sendStart(0, pulsePayload, sizeof pulsePayload, 1);
    Serial.println("]");
    digitalWrite(PIN_LED, LOW);
}
Exemplo n.º 15
0
void rf12_sendStart (void* ptr, uint8_t len) 
{
    memcpy((void*) rf12_data, ptr, len);

    rf12_sendStart();
}
Exemplo n.º 16
0
void AQERF_Remote::transmit(void){
    // put the base station address into the packet before sending
    memcpy(packet + AQERF_DESTINATION_BASE_ADDRESS_OFFSET, base_station_address, AQERF_DESTINATION_BASE_ADDRESS_LENGTH);
    rf12_sendStart(0, packet, AQERF_REMOTE_STATION_DATUM_PACKET_LENGTH);
}
Exemplo n.º 17
0
/// @details
/// Wait until transmission is possible, then start it as soon as possible.
/// @note This uses a (brief) busy loop and will discard any incoming packets.
/// @param hdr The header contains information about the destination of the
///            packet to send, and flags such as whether this should be
///            acknowledged - or if it actually is an acknowledgement.
/// @param ptr Pointer to the data to send as packet.
/// @param len Number of data bytes to send. Must be in the range 0 .. 65.
void rf12_sendNow (uint8_t hdr, const void* ptr, uint8_t len) {
    while (!rf12_canSend())
        rf12_recvDone(); // keep the driver state machine going, ignore incoming
    rf12_sendStart(hdr, ptr, len);
}
Exemplo n.º 18
0
/// @deprecated Use the 3-arg version, followed by a call to rf12_sendWait.
void rf12_sendStart (uint8_t hdr, const void* ptr, uint8_t len, uint8_t sync) {
    rf12_sendStart(hdr, ptr, len);
    rf12_sendWait(sync);
}
Exemplo n.º 19
0
/// @details
/// Switch to transmission mode and send a packet.
/// This can be either a request or a reply.
///
/// Notes
/// -----
///
/// The rf12_sendStart() function may only be called in two specific situations:
///
/// * right after rf12_recvDone() returns true - used for sending replies /
///   acknowledgements
/// * right after rf12_canSend() returns true - used to send requests out
///
/// Because transmissions may only be started when there is no other reception
/// or transmission taking place.
///
/// The short form, i.e. "rf12_sendStart(hdr)" is for a special buffer-less
/// transmit mode, as described in this
/// [weblog post](http://jeelabs.org/2010/09/15/more-rf12-driver-notes/).
///
/// The call with 4 arguments, i.e. "rf12_sendStart(hdr, data, length, sync)" is
/// deprecated, as described in that same weblog post. The recommended idiom is
/// now to call it with 3 arguments, followed by a call to rf12_sendWait().
/// @param hdr The header contains information about the destination of the
///            packet to send, and flags such as whether this should be
///            acknowledged - or if it actually is an acknowledgement.
/// @param ptr Pointer to the data to send as packet.
/// @param len Number of data bytes to send. Must be in the range 0 .. 65.
void rf12_sendStart (uint8_t hdr, const void* ptr, uint8_t len) {
    rf12_len = len;
    memcpy((void*) rf12_data, ptr, len);
    rf12_sendStart(hdr);
}