Arduino sin firmar int a int con nRF24L01 + biblioteca

2

Estoy intentando enviar un entero a través de un nodo Rf24 a otro. Desafortunadamente, las funciones de radio.write () envían un int sin firmar solamente. ¿Cómo puedo enviar una frase o un entero a través de ella?

EDITAR: este es el enlace a la biblioteca https://github.com/maniacbug/RF24

Este es el código del transmisor & receptor:

/*
 Copyright (C) 2011 J. Coliz <[email protected]>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Example RF Radio Ping Pair
 *
 * This is an example of how to use the RF24 class.  Write this sketch to two different nodes,
 * connect the role_pin to ground on one.  The ping node sends the current time to the pong node,
 * which responds by sending the value back.  The ping node can then see how long the whole cycle
 * took.
 */

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(8,7);

// sets the role of this unit in hardware.  Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const int role_pin = 3;

//
// Topology
//

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  The hardware itself specifies
// which node it is.
//
// This is done through the role_pin
//

// The various roles supported by this sketch
typedef enum { role_ping_out = 1, role_pong_back } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};

// The role of the current running sketch
role_e role;

void setup(void)
{
  //
  // Role
  //

  // set up the role pin
  pinMode(role_pin, INPUT);
  digitalWrite(role_pin,HIGH);
  delay(20); // Just to get a solid reading on the role pin

  // read the address pin, establish our role
  if ( ! digitalRead(role_pin) )
    role = role_ping_out;
  else
    role = role_pong_back;

  //
  // Print preamble
  //

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/pingpair/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);

  //
  // Setup and configure rf radio
  //

  radio.begin();

  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15);

  // optionally, reduce the payload size.  seems to
  // improve reliability
  radio.setPayloadSize(8);

  //
  // Open pipes to other nodes for communication
  //

  // This simple sketch opens two pipes for these two nodes to communicate
  // back and forth.
  // Open 'our' pipe for writing
  // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)

  if ( role == role_ping_out )
  {
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1,pipes[1]);
  }
  else
  {
    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1,pipes[0]);
  }

  //
  // Start listening
  //

  radio.startListening();

  //
  // Dump the configuration of the rf unit for debugging
  //

  radio.printDetails();
}

void loop(void)
{
  //
  // Ping out role.  Repeatedly send the current time
  //

  if (role == role_ping_out)
  {
    // First, stop listening so we can talk.
    radio.stopListening();

    // Take the time, and send it.  This will block until complete
    unsigned long time = millis();
    printf("Now sending %lu...",time);
    bool ok = radio.write( &time, sizeof(unsigned long) );

    if (ok)
      printf("ok...");
    else
      printf("failed.\n\r");

    // Now, continue listening
    radio.startListening();

    // Wait here until we get a response, or timeout (250ms)
    unsigned long started_waiting_at = millis();
    bool timeout = false;
    while ( ! radio.available() && ! timeout )
      if (millis() - started_waiting_at > 200 )
        timeout = true;

    // Describe the results
    if ( timeout )
    {
      printf("Failed, response timed out.\n\r");
    }
    else
    {
      // Grab the response, compare, and send to debugging spew
      unsigned long got_time;
      radio.read( &got_time, sizeof(unsigned long) );

      // Spew it
      printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
    }

    // Try again 1s later
    delay(1000);
  }

  //
  // Pong back role.  Receive each packet, dump it out, and send it back
  //

  if ( role == role_pong_back )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      unsigned int got_time_unsigned;
      int got_time = (int) got_time_unsigned;
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( &got_time_unsigned, sizeof(unsigned long) );

        // Spew it
        printf("Got payload %lu...",(got_time));

    // Delay just a little bit to let the other unit
    // make the transition to receiver
    delay(20);
      }

      // First, stop listening so we can talk
      radio.stopListening();

      // Send the final one back.
      radio.write( &got_time, sizeof(unsigned long) );
      printf("Sent response.\n\r");

      // Now, resume listening so we catch the next packets.
      radio.startListening();
    }
  }
}
// vim:cin:ai:sts=2 sw=2 ft=cpp

Aquí es donde ocurre la magia:

unsigned long time = millis();
        printf("Now sending %lu...",time);
        bool ok = radio.write( &time, sizeof(unsigned long) );

Aquí es donde la información se recibe y se muestra:

unsigned long got_time;
      radio.read( &got_time, sizeof(unsigned long) );

      // Spew it
      printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
    
pregunta Radolino

3 respuestas

4

Ahora que ha incluido la biblioteca, las funciones read y write se declaran de la siguiente manera:

bool read( void* buf, uint8_t len );
bool write( const void* buf, uint8_t len );

Entonces, el primer parámetro es un puntero a cualquier tipo de datos seguido de la longitud a transferir. En tu caso, puedes usar algo como:

int16_t my_var;
bool ok = radio.write( &my_var, sizeof(my_var) );
radio.read( & my_var, sizeof(my_var) );

Normalmente prefiero incluir el nombre de la variable en la llamada a sizeof en lugar del tipo de datos para que si lo cambias en el futuro no tengas que recordar cambiarlo en dos o más lugares. Para una cadena, exactamente el mismo código funcionaría siempre que se declare como una longitud fija, por ejemplo:

char my_var[10] = "Test";

Solo tenga cuidado al usar cadenas, ya que permite el carácter adicional requerido para su terminación nula, por lo que el ejemplo anterior podría contener un máximo de nueve caracteres.

    
respondido por el PeterJ
2

Para ampliar lo que dijeron efox29 y vicatcu, en principio no hay nada que le impida enviar sus datos a un int sin signo (sospecho que la función usa un uint8_t) y luego volver a lanzar en el otro extremo, siempre que ambos extremos puedan ponerse de acuerdo sobre qué el tipo original era (por ejemplo, si envías un número entero pero lo devuelves a un carácter no tiene sentido).

Cuando cambia entre firmado y sin firmar, todo lo que cambia es la interpretación cuando se aplican operaciones matemáticas. Por ejemplo, en unsigned usted se desplaza de cero al número positivo más alto en lugar de volverse negativo, y con algo como el complemento a 2, los bits subyacentes ni siquiera cambiarán.

Sin embargo, para su aplicación podría haber otro escollo, si el entero que desea enviar es más ancho que la función, por ejemplo, si su entero tiene 16 bits de ancho pero su función solo espera un uint8_t, los bytes alto y bajo debe enviarse por separado, es decir, reduciendo 8 bits hacia abajo para una llamada a la función write () y truncando los 8 bits superiores para otra. El ancho de un entero depende de la plataforma, pero sospecho que sus 16 bits para su Arduino se basan en la referencia del idioma .

Si proporciona un enlace a la biblioteca de radio que está utilizando, también puede obtener mejores respuestas.

    
respondido por el Sam M-G
0

He hecho mi propia biblioteca. Creo que lo encontrarás atractivo y fácil de usar. Mira el video de ejemplo.

enlace

Podrás enviar un int, unsigned int, long, unsigned long, byte; Básicamente, los tipos más comunes utilizados al programar con el lenguaje Arduino. Y también matrices y String.

La biblioteca estará terminada el lunes o el martes.

    
respondido por el user26104

Lea otras preguntas en las etiquetas