< async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"">

Sunday, December 29, 2013

Wirelessly send strings to 8*8 led matrix with NRF24L01 Transceiver- scrolling tweets

ADVERTISEMENT
Using wireless connectivity in arduino project is really cool and can be easily achived with small cost effective nrf2401 modules. Most of the examples shows sending integer or float values but the module can send or receive strings and floats. Here is a small project which is based on a serial chat from Stanley. In this case am sending a set of strings from an arduino attached to a raspberry pi ( you could directly attach an nrf24l01 to the pi, more on it later) and the string (for eg tweets from a local news paper) will be wirelessly send to my scrolling 8*8 led matrix placed on the kitchen.




There are two parts. One arduino with nrf module is connected to a raspberry pi and receives the strings over serial and is achieved with python serial as follows (basic block is shown)

#!/usr/bin/python
import serial
import sys
ser = serial.Serial('/dev/ttyACM0', 9600)
ser.write("string goes here.......")


Sources - Raspberry-serial-arduino transmit part (it can receive as well!)

/* credits to Author : Stanley Seow
e-mail : [email protected] 
modified for dotmatrix led 
This will send a string from the Raspberry pi or PC to a remote NRF24l01 connected 8*8 led matrix
On the raspberry pi you can use pyserial to write to the arduino

Connecting the rf module is same as my previos post

See here http://blog.riyas.org/2013/12/working-quick-start-guide-for-nrf24l01.html

*/

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9,10);
const uint64_t pipes[2] = { 0xDEDEDEDEE7LL, 0xDEDEDEDEE9LL };
boolean stringComplete = false;  
static int dataBufferIndex = 0;
boolean stringOverflow = false;
char charOverflow = 0;
char SendPayload[31] = "";
char RecvPayload[31] = "";
char serialBuffer[31] = "";

void setup(void) {
 
  Serial.begin(9600);
  analogReference(INTERNAL);
  radio.begin();
  
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(70);
  
  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setCRCLength(RF24_CRC_16);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);  
  
  radio.startListening();
  radio.printDetails(); 
  delay(500);

}

void loop(void) {   
  
  nRF_receive();
  serial_receive();
  
} 
void serialEvent() {
  while (Serial.available() > 0 ) {
      char incomingByte = Serial.read();
      
      if (stringOverflow) {
         serialBuffer[dataBufferIndex++] = charOverflow;  // Place saved overflow byte into buffer
         serialBuffer[dataBufferIndex++] = incomingByte;  // saved next byte into next buffer
         stringOverflow = false;                          // turn overflow flag off
      } else if (dataBufferIndex > 31) {
         stringComplete = true;        // Send this buffer out to radio
         stringOverflow = true;        // trigger the overflow flag
         charOverflow = incomingByte;  // Saved the overflow byte for next loop
         dataBufferIndex = 0;          // reset the bufferindex
         break; 
      } 
      else if(incomingByte=='\n'){
          serialBuffer[dataBufferIndex] = 0; 
          stringComplete = true;
      } else {
          serialBuffer[dataBufferIndex++] = incomingByte;
          serialBuffer[dataBufferIndex] = 0; 
      }          
  } 
} 

void nRF_receive(void) {
  int len = 0;
  if ( radio.available() ) {
      bool done = false;
      while ( !done ) {
        len = radio.getDynamicPayloadSize();
        done = radio.read(&RecvPayload,len);
        delay(5);
      }
  
    RecvPayload[len] = 0; // null terminate string
    RecvPayload[0] = 0;  // Clear the buffers
  }  

} 

void serial_receive(void){
  
  if (stringComplete) {
        strcat(SendPayload,serialBuffer);      
        // swap TX & Rx addr for writing
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(0,pipes[0]);  
        radio.stopListening();
        bool ok = radio.write(&SendPayload,strlen(SendPayload));
        stringComplete = false;
        // restore TX & Rx addr for reading       
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]); 
        radio.startListening();  
        SendPayload[0] = 0;
        dataBufferIndex = 0;
        
  } 
}    


Here is the led matrix receiver
 Library Timed action can be downloaded here (and details are here )

/*
Serial string receiving arduino with an 8*8 led matrix to show the text
wiring of nrf24l01 is same as the buddy program
Credits to: 
nRF Serial Chat by Stanley Seow

*/

//#include <LiquidCrystal.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"


#include <HCDotMatrix.h>
#include <TimedAction.h>

/* Led matrix related code starts here depends on direct drive/ shift register or serial control of 8*8 led matrix i used the one from hobby component*/
HCDotMatrix HCDotMatrix(5,6,4,17,16,15,14,8,7,3,2);
int TextPosition;
/* Used to control the scroll speed. */
int ScrollCounter = 0;
char charBuf[31]= "------";
TimedAction scrollerAction = TimedAction(20,scroller);
/* Led matrix related code ends here */

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;
} 

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}


RF24 radio(9,10);

const uint64_t pipes[2] = { 0xDEDEDEDEE7LL, 0xDEDEDEDEE9LL };

boolean stringComplete = false;  // whether the string is complete
static int dataBufferIndex = 0;
boolean stringOverflow = false;
char charOverflow = 0;

char SendPayload[31] = "";
char RecvPayload[31] = "";
char serialBuffer[31] = "";

void setup(void) {
 
  Serial.begin(9600);
  radio.begin();
  
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(70);
  
  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setCRCLength(RF24_CRC_16);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);  
  
  radio.startListening();
  radio.printDetails();
  delay(500);

}

void loop(void) {
  
  nRF_receive();
  serial_receive();
  scrollerAction.check(); 
  
} 

void serialEvent() {
  while (Serial.available() > 0 ) {
      char incomingByte = Serial.read();
      
      if (stringOverflow) {
         serialBuffer[dataBufferIndex++] = charOverflow;  // Place saved overflow byte into buffer
         serialBuffer[dataBufferIndex++] = incomingByte;  // saved next byte into next buffer
         stringOverflow = false;                          // turn overflow flag off
      } else if (dataBufferIndex > 31) {
         stringComplete = true;        // Send this buffer out to radio
         stringOverflow = true;        // trigger the overflow flag
         charOverflow = incomingByte;  // Saved the overflow byte for next loop
         dataBufferIndex = 0;          // reset the bufferindex
         break; 
      } 
      else if(incomingByte=='\n'){
          serialBuffer[dataBufferIndex] = 0; 
          stringComplete = true;
      } else {
          serialBuffer[dataBufferIndex++] = incomingByte;
          serialBuffer[dataBufferIndex] = 0; 
      }          
  } // end while()
} // end serialEvent()

void nRF_receive(void) {
  
  int len = 0;
  if ( radio.available() ) {
      bool done = false;
      while ( !done ) {
        len = radio.getDynamicPayloadSize();
        done = radio.read(&RecvPayload,len);
        delay(5);
      }
  
    RecvPayload[len] = 0; // null terminate string
    Serial.print("R:");
    Serial.print(RecvPayload);
    Serial.println();
    RecvPayload[0] = 0;  // Clear the buffers
  }  

} // end nRF_receive()

void serial_receive(void){
  
  if (stringComplete) {
        
        strcat(SendPayload,serialBuffer);
              
        // swap TX & Rx addr for writing
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(0,pipes[0]);  
        radio.stopListening();
        bool ok = radio.write(&SendPayload,strlen(SendPayload));
        stringComplete = false;

        // restore TX & Rx addr for reading       
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]); 
        radio.startListening();  
        SendPayload[0] = 0;
        dataBufferIndex = 0;
        
  } // endif
} // end serial_receive()  


/* put the text showing routine specific to your led matrix drive here and assign to recvpayload */

void scroller()
{
    
  /* Stores the position index for the portion of text to diplay */
    ScrollCounter++;
  
  /* Has enough time passed to move the text by one position ?*/
  if (ScrollCounter >= 10)
  {
    /* Have we got to the end of the text (24 characters x 8 pixels wide)? 
       If so go back to the start.*/
       
    if (TextPosition > (8*31))
      TextPosition = 0;
   
    /* Output a string to the matrix buffer and specify the display 
       column position */
     
    HCDotMatrix.print(RecvPayload,TextPosition); //RecvPayload charBuf
     
    TextPosition++;
    ScrollCounter = 0;
  }
  
  /* Refresh the display. This must be run continuously */
  HCDotMatrix.UpdateMatrix();
  
  
}


No comments:

Post a Comment