API Xbee confusion

So Im working on a project (Wooohoo)
To implement a pace clock system that is wireless using 4 Xbee's and 4 Arduinos

CORD -> 3X ROUT and each ROUT -> CORD at least in theory this is how I would like to setup this

There are 2 elements that matter is the Time from the router from when the last time that button was pushed
and then there is the level of WIP = This is just a number that decreases with each button push is hit but in creases with the router to the right of them has been pushed also

AKA R"X" (WIP) -> R1(3) R2(3) R3(3) now say R1 pushes there button it would look like this -> R1(2) R2(4) R3(3) given that R2 hasnt pushed there button

So I'm not sure if im losing it but it seems like the world really starts to look grey when I introduce API mode...

Here is an example of the code if all I cared about was a single serial output onto a serial LCD screen I have....

const int TxPin = 6;


#include <SoftwareSerial.h>
SoftwareSerial mySerial = SoftwareSerial(255, TxPin);
int button = 7;  //button attached to pin 7
int val;        // reads the button state in loop
int val2;       // reads the button state a second time
int state;      // reads the button state in setup and stores it  could have called this button old    
int press = 1; // press counter, i set this to 1 so when the first button is pressed it will give a value of 0 activating the first pin
unsigned long time;
unsigned long time2;
unsigned long time3;
unsigned long time4;
int RedO = 13;
int YelO = 12;
int GrnO = 11;

int button1hit = 0;  // secondary code switch stops code running before a button has been pressed


void setup() {
  pinMode(button, INPUT);

  pinMode(TxPin, OUTPUT);
  pinMode(RedO, OUTPUT);
  pinMode(YelO, OUTPUT);
  pinMode(GrnO, OUTPUT);
       
  state = digitalRead(button);  // read button state and store it to reference against later

  digitalWrite(TxPin, HIGH);
  digitalWrite(GrnO, HIGH);
  
  mySerial.begin(9600);
  delay(100);
  mySerial.write(12);                 // Clear             
  mySerial.write(17);                 // Turn backlight on
  delay(5);                           // Required delay
  mySerial.print("UNT EE");  // First line
  mySerial.write(13);                 // Form feed
  mySerial.print("Project 6");   // Second line
  delay(3000);                        // Wait 3 seconds
}



void loop()
{
  time = millis();
  time2 = ((millis()-time3)/1000) % 60; THIS IS JUST ME GETTING FANCY AND ISNT NEEDED ITS JUST MAKING THE TIME LOOK LIKE A CLOCK
  time4 = (((millis()-time3)/1000) / 60) % 60;

  val = digitalRead(button);
  delay(10);          // wait 10 millis to counter debounce
  val2 = digitalRead(button); //check again to see if button is pressed
if (time2 == 10){
digitalWrite(RedO,HIGH);
digitalWrite(YelO,LOW);}
if (time2 == 6){
  digitalWrite(YelO,HIGH);
digitalWrite(GrnO,LOW);}



  
if ((val == val2) && (val != state) && (val == HIGH))
  {              
    press++; // counts button presses
    if (press > 1)
    {
      press = 0;    //when button press count passes 1 it resets to zero
    }

    if (press == 0 or press == 1)
    {
mySerial.write(12);                 // Clear             
  delay(5);                           // Required delay
  mySerial.print("Time=");  // First line
  mySerial.print(time4);
  mySerial.print(":");
  mySerial.print(time2);
  mySerial.write(13);                 // Form feed
  mySerial.print("TIMETAKEN");   // Second line
  mySerial.write(212);                // Quarter note
   time3=time ;
 digitalWrite(RedO,LOW);
 digitalWrite(YelO,LOW);
 digitalWrite(GrnO,HIGH);
 }
  }

  state = val;
}

The 3 LEDS just pace the "USER" into hurrying giving them a visual indicator...

I have a few questions for the arduino world :slight_smile:

Can I just use AT Mode? I can accept dropping the WIP feature if it means I can make more progress quicker.....
Last is there an easy way in API mode to send strings or "Longs" across api mode and how can they be read?

Thank you for your help to the new man!

  pinMode(TxPin, OUTPUT);

Hey, SoftwareSerial instance! I know I said this was your pin. You don't mind if I diddle with it, anyway, do you.

Yes, the instance DOES mind.

Can I just use AT Mode?

If every Arduino with XBee can, at any time, scream at the coordinator, how will the coordinator know who is talking? That's what AT mode does. API mode sends packets that contain, among other things, the ID of the sender.

Last is there an easy way in API mode to send strings or "Longs" across api mode

Andrew Rapp wrote a really nice XBee library that makes use of API mode easy. So, the answer to this question is yes.

and how can they be read?

Depends on how they are sent.

Thanks for such quick feedback

I think the largest parts of my misunderstandings is that the output the Xbees are giving outputs to the coordinator are in some weird ascii that I have yet to understand or how to even use....
stuff like `~.~.~.~.3G without anything of use to me yet?

The library for API Xbee I am very greatfull for but even the examples are just baffling to me...

/**
 * Copyright (c) 2009 Andrew Rapp. All rights reserved.
 *
 * This file is part of XBee-Arduino.
 *
 * XBee-Arduino is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * XBee-Arduino is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XBee-Arduino.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <XBee.h>
#include <NewSoftSerial.h>

/*
This example is for Series 2 XBee
 Sends a ZB TX request with the value of analogRead(pin5) and checks the status response for success
*/

// create the XBee object
XBee xbee = XBee();

uint8_t payload[] = { 0, 0 };

// SH + SL Address of receiving XBee
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x403e0f30);
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

int pin5 = 0;

int statusLed = 13;
int errorLed = 13;

void flashLed(int pin, int times, int wait) {

  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);

    if (i + 1 < times) {
      delay(wait);
    }
  }
}

void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);

  xbee.begin(9600);
}

void loop() {   
  // break down 10-bit reading into two bytes and place in payload
  pin5 = analogRead(5);
  payload[0] = pin5 >> 8 & 0xff;
  payload[1] = pin5 & 0xff;

  xbee.send(zbTx);

  // flash TX indicator
  flashLed(statusLed, 1, 100);

  // after sending a tx request, we expect a status response
  // wait up to half second for the status response
  if (xbee.readPacket(500)) {
    // got a response!

    // should be a znet tx status            	
    if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
      xbee.getResponse().getZBTxStatusResponse(txStatus);

      // get the delivery status, the fifth byte
      if (txStatus.getDeliveryStatus() == SUCCESS) {
        // success.  time to celebrate
        flashLed(statusLed, 5, 50);
      } else {
        // the remote XBee did not receive our packet. is it powered on?
        flashLed(errorLed, 3, 500);
      }
    }
  } else if (xbee.getResponse().isError()) {
    //nss.print("Error reading packet.  Error code: ");  
    //nss.println(xbee.getResponse().getErrorCode());
  } else {
    // local XBee did not provide a timely TX Status Response -- should not happen
    flashLed(errorLed, 2, 50);
  }

  delay(1000);
}

Things like this ....

uint8_t payload[] = { 0, 0 };

or even this

 // break down 10-bit reading into two bytes and place in payload
  pin5 = analogRead(5);
  payload[0] = pin5 >> 8 & 0xff;
  payload[1] = pin5 & 0xff;

I would just want to send a string to the cordinator??

And on the receiving end

/**
 * Copyright (c) 2009 Andrew Rapp. All rights reserved.
 *
 * This file is part of XBee-Arduino.
 *
 * XBee-Arduino is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * XBee-Arduino is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XBee-Arduino.  If not, see <http://www.gnu.org/licenses/>.
 */
 
#include <XBee.h>
#include <NewSoftSerial.h>

/*
This example is for Series 2 XBee
Receives a ZB RX packet and sets a PWM value based on packet data.
Error led is flashed if an unexpected packet is received
*/

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle 
ZBRxResponse rx = ZBRxResponse();
ModemStatusResponse msr = ModemStatusResponse();

int statusLed = 13;
int errorLed = 13;
int dataLed = 13;

void flashLed(int pin, int times, int wait) {
    
    for (int i = 0; i < times; i++) {
      digitalWrite(pin, HIGH);
      delay(wait);
      digitalWrite(pin, LOW);
      
      if (i + 1 < times) {
        delay(wait);
      }
    }
}

void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
  pinMode(dataLed,  OUTPUT);
  
  // start serial
  xbee.begin(9600);
  
  flashLed(statusLed, 3, 50);
}

// continuously reads packets, looking for ZB Receive or Modem Status
void loop() {
    
    xbee.readPacket();
    
    if (xbee.getResponse().isAvailable()) {
      // got something
      
      if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        // got a zb rx packet
        
        // now fill our zb rx class
        xbee.getResponse().getZBRxResponse(rx);
            
        if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
            // the sender got an ACK
            flashLed(statusLed, 10, 10);
        } else {
            // we got it (obviously) but sender didn't get an ACK
            flashLed(errorLed, 2, 20);
        }
        // set dataLed PWM to value of the first byte in the data
        analogWrite(dataLed, rx.getData(0));
      } else if (xbee.getResponse().getApiId() == MODEM_STATUS_RESPONSE) {
        xbee.getResponse().getModemStatusResponse(msr);
        // the local XBee sends this response on certain events, like association/dissociation
        
        if (msr.getStatus() == ASSOCIATED) {
          // yay this is great.  flash led
          flashLed(statusLed, 10, 10);
        } else if (msr.getStatus() == DISASSOCIATED) {
          // this is awful.. flash led to show our discontent
          flashLed(errorLed, 10, 10);
        } else {
          // another status
          flashLed(statusLed, 5, 10);
        }
      } else {
      	// not something we were expecting
        flashLed(errorLed, 1, 25);    
      }
    } else if (xbee.getResponse().isError()) {
      //nss.print("Error reading packet.  Error code: ");  
      //nss.println(xbee.getResponse().getErrorCode());
    }
}

Things like this

#include <NewSoftSerial.h> ??

Or

        if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
            // the sender got an ACK
            flashLed(statusLed, 10, 10);
        } else {
            // we got it (obviously) but sender didn't get an ACK
            flashLed(errorLed, 2, 20);
        }
        // set dataLed PWM to value of the first byte in the data
        analogWrite(dataLed, rx.getData(0));
      } else if (xbee.getResponse().getApiId() == MODEM_STATUS_RESPONSE) {
        xbee.getResponse().getModemStatusResponse(msr);
        // the local XBee sends this response on certain events, like association/dissociation

Im just feeling so defeated because I just want to send a string to the other arduino :frowning:

Thanks for your quick response BTW.....

So I think I was using an Old Xbee library :slight_smile:

Once again you where out there saving the day!

Things like this ....

payload is an array to contain the data you want to send. The data in the example you showed is sent in binary form. If you want to send in ASCII, instead:

uint8_t payload[32];
int temp = 95;
sprintf((char *)payload, "It's hot: %d", temp);

Then, send payload.

I would just want to send a string to the cordinator??

I'm not sure what sending "It's a beautiful day in the neighborhood" to the coordinator would accomplish, but perhaps you had a different string in mind.