How to make nodemcu auto connect strong wifi signal [closed] - arduino

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
To many wifi but need to connect strong signal (dynamic switch between wifi look like mobilephone)

Automatically Connecting to the strongest network
Scan networks
int8_t scanNetworks(bool async, bool show_hidden, uint8 channel, uint8* ssid);
You can either continuously scan for available networks or
do a periodic check using the scanNetworks function which returns the number of networks found.
scanNetworks will return the number (8-bit integer) of networks found.
By default async flag is set to false so your program will halt while nodemcu is
scaning networks.
You can set it to true so your program keeps running while networks are being scanned.
Don't worry about other arguments, they are set to default value.
You can change them if you want just by passing values for those as well.
Remember that while you are scanning for networks your Wifi mode is switched to station
so if you want to continuously scan networks while you are in access point mode,
your station will be turned off. And you will have to restart the access point
after scan is completed.
While scan is running the scanNetworks function will return WIFI_SCAN_RUNNING
You can process the results if
(WiFi.scanNetworks() != WIFI_SCAN_RUNNING)
Processing the results of WiFi Scan
int_32t WiFi.RSSI(unit_8t i); // returns the network strength of ith network
String WiFi.SSID(uint8_t i); // returns the ssid of ith network
Results are indexed in descending order of strength,
so the 0th result has the highest strength, and nth result has the least strength
Once the scan is complete, provided that you know the passwords of the available networks
you can directly connect to the 0th result by writing
WiFi.begin(WiFi.SSID(0), password);
But its always a good idea to check whether you know that network.
You can easily do that by having a list of the known (trusted) networks.
and comparing every result's ssid to every member of the list.
If they match, then you can start the connection.
char knownNetworks [][] =
{
"Network1",
"Network2",
};
#define KNOWN_NETWORKS 2
int8_t networkResult = WiFi.scanNetworks();
for(int i = 0; i < KNOWN_NETWORKS; i++)
for(int j = 0; j < scanResult; j++)
if(strcpy(knownNetworks[i], WiFi.SSID(j) == 0)
WiFi.begin(knownNetworks[i], password);
I hope this was helpful!
If You have any questions, I would be happy to help.

Please try this
// #include WiFi Library
#include <ESP8266WiFi.h>
/* Serial Baud Rate */
#define SERIAL_BAUD 9600
/* Delay paramter for connection. */
#define WIFI_DELAY 500
/* Max SSID octets. */
#define MAX_SSID_LEN 32
/* Wait this much until device gets IP. */
#define MAX_CONNECT_TIME 30000
/* SSID that to be stored to connect. */
char ssid[MAX_SSID_LEN] = "";
/* Scan available networks and sort them in order to their signal strength. */
void scanAndSort() {
memset(ssid, 0, MAX_SSID_LEN);
int n = WiFi.scanNetworks();
Serial.println("Scan complete!");
if (n == 0) {
Serial.println("No networks available.");
} else {
Serial.print(n);
Serial.println(" networks discovered.");
int indices[n];
for (int i = 0; i < n; i++) {
indices[i] = i;
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
std::swap(indices[i], indices[j]);
}
}
}
for (int i = 0; i < n; ++i) {
Serial.println("The strongest open network is:");
Serial.print(WiFi.SSID(indices[i]));
Serial.print(" ");
Serial.print(WiFi.RSSI(indices[i]));
Serial.print(" ");
Serial.print(WiFi.encryptionType(indices[i]));
Serial.println();
if(WiFi.encryptionType(indices[i]) == ENC_TYPE_NONE) {
memset(ssid, 0, MAX_SSID_LEN);
strncpy(ssid, WiFi.SSID(indices[i]).c_str(), MAX_SSID_LEN);
break;
}
}
}
}
void setup() {
// Scan, Sort, and Connect to WiFi
Serial.begin(SERIAL_BAUD);
Serial.println("Scanning for open networks...");
if(WiFi.status() != WL_CONNECTED) {
/* Clear previous modes. */
WiFi.softAPdisconnect();
WiFi.disconnect();
WiFi.mode(WIFI_STA);
delay(WIFI_DELAY);
/* Scan for networks to find open guy. */
scanAndSort();
delay(WIFI_DELAY);
/* Global ssid param need to be filled to connect. */
if(strlen(ssid) > 0) {
Serial.print("Connecting to ");
Serial.println(ssid);
/* No pass for WiFi. We are looking for non-encrypteds. */
WiFi.begin(ssid);
unsigned short try_cnt = 0;
/* Wait until WiFi connection but do not exceed MAX_CONNECT_TIME */
while (WiFi.status() != WL_CONNECTED && try_cnt < MAX_CONNECT_TIME / WIFI_DELAY) {
delay(WIFI_DELAY);
Serial.print(".");
try_cnt++;
}
if(WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("Connection Successful!");
Serial.println("Your device IP address is ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Connection FAILED");
}
} else {
Serial.println("No open networks available. :-(");
}
}
}
void loop () {
}

Related

How do i send data from my esp8266 light sensor to blynk?

I am trying to know whether the lights have tripped using a light sensor to detect light intensity. However, i do not know how to upload my data onto blynk, as i am new to blynk and new to arduino as well. Below is my code. I tried using a telegram bot to get the data but somehow it stopped working and i am finding alternatives to get the data remotely. If there are any other methods other than Blynk please suggest too.
#include <ESP8266WiFi.h> // WIFI LIBRARY
#include <WiFiClient.h> //CLIENT LIBRARY
#include <ESP8266WebServer.h> //WEBSERVICER LIBRARY
#include <ESP8266HTTPClient.h> //HTTP CLIENT LIBRARY
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "ArchiEngStudio";
char pass[] = "a12345678";
int CNT = 0, sent, i, j;
float count = 0;
int limit = 800; // SET LIMIT HERE
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
void loop() {
float reading = analogRead(A0);
Serial.println(reading);
delay(3000);
/* NO LIGHT CONDITION */
if (reading < limit)
{
if (CNT < 1) // CHECK LOOP ONLY RUNS ONCE
{
count = 0;
for (i=0; i<10; i++) //TAKING 10 READINGS TO CHECK IF LIGHTS ARE REALLY OFF
{
delay(1000);
int read2 = analogRead(A0);
Serial.println(read2);
if (read2 < limit)
{
Serial.println("(1) No Light ...");
}
else
{
Serial.println("(1) Light on...");
i= i+20;
}
}
if (i < 11) // IF ALL 10 READINGS SHOW THAT LIGHTS ARE OFF, SEND MESSAGE
{
if (sent == 0)
{
Serial.println("Tripped!");
sent = 1;
}
}
}
CNT++;
}
else
{
CNT = 0;
}
/* LIGHTS ON CONDITION */
if (sent == 1) //ONLY ALLOWED IF LIGHTS WERE OFF
{
if (reading >= limit)
{
for (j=0; j<10; j++) //TAKING 10 READINGS TO CHECK IF LIGHTS ARE REALLY ON
{
delay(1000);
int read3 = analogRead(A0);
Serial.println(read3);
if (read3 >= limit)
{
Serial.println("(2) Light on...");
}
else
{
Serial.println("(2) No light...");
j= i+10;
}
}
if (j < 11) //IF ALL 10 READINGS SHOW THAT LIGHTS ARE ON, SEND MESSAGE
{
Serial.println("Light on!");
sent = 0;
}
}
}
}
Blynk provides a decent way to display your data and is very easy to use once you are familiar with the concept.
You can store your reading variable in a virtual pin 'Vx' on the Blynk server by adding this line to your code:
Blynk.virtualWrite(Vx, reading);
If you want to display it on the app just use "value display" widget and configure it to display your virtual pin 'Vx'.

I could not make IRsend from the IRremote library to work

Hello i am using an arduino mkr1000 so send and IR signal using the IRremote library for mkr1000 IRremote library. I am having problems with IRsend.
First i used the IRdump example to get the data from my remote button. When i finished this i tried the IRsend example but it seems to be not working.
I temporarily replaced with a ordinary LED to show if it is really blinking, but it is not. I have tested the both the ordinary LED and IR LED that they worked.
I also think that i have wired the LED correctly according to the example
PIN 3 -> LED -> Resistor -> Ground
My circuit was further confirmed correct when i upload a sketch that makes it blink.
Basically i am trying to send a NEC 32bit signal, 0x2FD807F
but i guess they were not able to finish the library of send for mkr1000???
in this post a comment was made with a code but did not really have any detail on how to use it.
here is where i am currently at
int IR_S = 3;
void setup()
{
pinMode(IR_S,OUTPUT);
}
void loop() {
IR_Sendcode(0x2FD807F);
delay(1000);
}
void IR_Send38KHZ(int x,int bit) //Generate 38KHZ IR pulse
{
for(int i=0;i<x;i++)//15=386US
{
if(bit==1)
{
digitalWrite(IR_S,1);
delayMicroseconds(9);
digitalWrite(IR_S,0);
delayMicroseconds(9);
}
else
{
digitalWrite(IR_S,0);
delayMicroseconds(20);
}
}
}
void IR_Sendcode(uint8_t data) // Send the data
{
for(int i=0;i<8;i++)
{
if((data&0x01)==0x01)
{
IR_Send38KHZ(23,1);
IR_Send38KHZ(64,0);
}
else
{
IR_Send38KHZ(23,1);
IR_Send38KHZ(21,0);
}
data=data>>1;
}
}
I while i was waiting for replies i created my own code. I have finished and tested it. It should theoretically work on any arduino.
/*
This is a code for NEC Infrared Transmission Protocol Transmitter
NEC specifications are
~ Carrier Frequency is 38kHz
* Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
* Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms
- a 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)
- a 4.5ms space
- the 8-bit address for the receiving device
- the 8-bit logical inverse of the address
- the 8-bit command
- the 8-bit logical inverse of the command
- a final 562.5µs pulse burst to signify the end of message transmission.
Example,
If the code recieved from the data dump from the IRremote library is 0x2FD807F
-0x02 is address
-0xFD is the inverse address
-0x80 is the command
-0x7F is the inverse command
THIS PROGRAM IS A BLOCKING PROGRAM
*/
#define IR 3
#define CarrierFreqInterval 11
void setup() {
pinMode(IR, OUTPUT);
digitalWrite(IR, LOW);
}
void loop() {
// unsigned long start = micros();
transmit(0x02FD807F);
// unsigned long ends = micros();
// unsigned long delta = ends - start;
// Serial.println(delta);
delay(500);
}
void transmit(uint32_t data) {
//Function for transmiting the data
uint32_t bitcount = 0x80000000;
// 9ms pulse burst
for (int i = 0; i < 355; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
// 4.5ms space
delayMicroseconds(4500);
//8bit address,adress inverse,command,command inverse
while ( bitcount != 0b0) {
if ((data & bitcount) == bitcount) {
pulseHIGH();
}
else {
pulseLOW();
}
bitcount = bitcount >> 1;
}
//final pulse burst
for (int i = 0; i < 21; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
}
void pulseHIGH() {
// Pulse 38KHz good for a LOGIC '1'
for (int i = 0; i < 21; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
delay(1);
delayMicroseconds(687.5);
}
void pulseLOW() {
// Pulse 38KHz good for a LOGIC '0'
for (int i = 0; i < 21; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
delayMicroseconds(562.5);
}

How to stop multiple reads of an RFID card

I'm using an 125Khz RFID module RDM6300 with arduino nano.
While the card is near the RFID reader the loop will read the card multiple times. I want it to read only once while the card is near the reader then read it again if a new connection is being made.
*This code is not writen by me, this is the source:
https://github.com/Wookai/arduino-rfid
// define constants for pins
//int SUCCESS = 10;
//int ERROR = 13;
// variables to keep state
int readVal = 0; // individual character read from serial
unsigned int readData[10]; // data read from serial
int counter = -1; // counter to keep position in the buffer
char tagId[11]; // final tag ID converted to a string
char* authorizedTags[4]; // array to hold the list of authorized tags
// fills the list of authorzied tags
void initAuthorizedTags() {
// add your own tag IDs here
authorizedTags[0] = "0400680B85";
authorizedTags[1] = "0400063EB9";
authorizedTags[2] = "040004F3F5";
authorizedTags[3] = "04006813AB";
}
void setup() {
Serial.begin(9600);
// pinMode(SUCCESS, OUTPUT);
//pinMode(ERROR, OUTPUT);
initAuthorizedTags();
}
// check if the tag ID we just read is any of the authorized tags
int checkTag() {
int i;
for (i = 0; i < 4; ++i) {
if (strcmp(authorizedTags[i], tagId) == 0) {
return 1;
}
}
return 0;
}
// convert the int values read from serial to ASCII chars
void parseTag() {
int i;
for (i = 0; i < 10; ++i) {
tagId[i] = readData[i];
}
tagId[10] = 0;
}
// once a whole tag is read, process it
void processTag() {
// convert id to a string
parseTag();
// print it
printTag();
// check if the tag is authorized
if (checkTag() == 1) {
tagSuccess(); // if so, perform an action (blink a led, open a door, etc...)
} else {
tagFailed(); // otherwise, inform user of failure
}
}
void printTag() {
Serial.print("Tag value: ");
Serial.println(tagId);
}
// perform an action when an authorized tag was read
void tagSuccess() {
Serial.println("Tag authorized.");
// here, we simply turn on the success LED for 2s
// digitalWrite(SUCCESS, HIGH);
//digitalWrite(ERROR, LOW);
// delay(2000);
}
// inform the user that the tag is not authorized
void tagFailed() {
Serial.println("Unauthorized access!");
//digitalWrite(SUCCESS, LOW);
// digitalWrite(ERROR, HIGH);
// delay(2000);
}
// this function clears the rest of data on the serial, to prevent multiple scans
void clearSerial() {
while (Serial.read() >= 0) {
; // do nothing
}
}
void loop() {
// turn LEDs off
// digitalWrite(SUCCESS, LOW);
// digitalWrite(ERROR, LOW);
if (Serial.available() > 0) {
// read the incoming byte:
readVal = Serial.read();
// a "2" signals the beginning of a tag
if (readVal == 2) {
counter = 0; // start reading
}
// a "3" signals the end of a tag
else if (readVal == 3) {
// process the tag we just read
processTag();
// clear serial to prevent multiple reads
clearSerial();
// reset reading state
counter = -1;
}
// if we are in the middle of reading a tag
else if (counter >= 0) {
// save valuee
readData[counter] = readVal;
// increment counter
++counter;
}
}
}
Thank you.
Thank you for your answers. I tried to accept the multiple reads and print only one but it keeps printing "already read" instead of reading the card first time, this is the code:
void printTag() {
if(strcmp(tagId,previous)==1){
strcpy(previous, tagId);
Serial.print("Tag value: ");
Serial.println(tagId);
}
else
{
Serial.print("already read");
}
}
I also tried to put the delay after end of tag but it still reads the card multiple times.
I tried another code, it still reads the tag multiple times.
#include <SoftwareSerial.h>
// RFID | Nano
// Pin 1 | D2
// Pin 2 | D3
SoftwareSerial Rfid = SoftwareSerial(2,3);
int timer=0;
int reference = 1000;
int card_status = 0;
void setup() {
// Serial Monitor to see results on the computer
Serial.begin(9600);
// Communication to the RFID reader
Rfid.begin(9600);
}
void read() {
// check, if any data is available
// as long as there is data available...
while(Rfid.available() > 0 ){
// read a byte
int r = Rfid.read();
// print it to the serial monitor
Serial.print(r, DEC);
Serial.print(" ");
}
// linebreak
Serial.println();
timer=0;
}
void loop()
{
if((Rfid.available() > 0 ) && (card_status == 0) )
{
read();
}
if((!Rfid.available() > 0 ) && (card_status == 1) )
{
card_status=0;
}
}
I'm sorry for the late response. I forgot about this topic.
I solved the problem by making the arduino wait for a response after writing the RFID code for the frist time.
I was able to do that because my arduino was sending the code to a C# application via serial port.
Here is how it works: the arduino prints the RFID code on the serial, from there it is picked up by the C# application which searches a database to see if the code is stored there. Depending on the result, the application prints a character('y' or 'n') which is picked up by the arduino. Depending on the character recieved, the arduino lights up a led ( green or red) and makes a noise. Now a new RFID reading can be made.
Here is the code:
#include <SoftwareSerial.h>
#include "RDM6300.h"
SoftwareSerial rdm_serial(8, 9);
RDM6300<SoftwareSerial> rdm(&rdm_serial);
String comanda;
char c="";
int led_verde = 2;
int led_rosu = 7;
int buzzer = 12;
int i;
void buzz(int n = 1)
{
for (int i = 0; i < n; i++) {
digitalWrite(buzzer, LOW);
delay(200);
digitalWrite(buzzer, HIGH);
delay(200);
}
}
void ledVerde()
{
digitalWrite(led_verde, HIGH);
buzz(1);
delay(1000);
digitalWrite(led_verde, LOW);
}
void ledRosu()
{
digitalWrite(led_rosu, HIGH);
buzz(3);
delay(1000);
digitalWrite(led_rosu, LOW);
}
void setup()
{
pinMode(led_verde, OUTPUT);
pinMode(led_rosu, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(led_verde, LOW);
digitalWrite(led_rosu, LOW);
digitalWrite(buzzer, HIGH);
Serial.begin(9600);
}
void loop()
{
static unsigned long long last_id = 0;
last_id = rdm.read();
rdm.print_int64(last_id);
Serial.println();
rdm_serial.end();
Serial.flush();
while(!Serial.available());
c=Serial.read();
if(c=='y')
{
ledVerde();
c="";
}
if(c=='n')
{
ledRosu();
}
Serial.flush();
last_id="";
c="";
rdm_serial.begin(9600);
}
You can find the RDM6300 library here: https://github.com/arliones/RDM6300-Arduino
Long time passed the original question, but maybe my answer would be useful for future visitors.
The RDM6300 works by:
automatically reading the data, and then
your code transfers the read data to the buffer for further processing.
Imagine it as a Baggage carousel in the airport. There are multiple luggage (data) on the carousel (reader), and you pick them one by one (transferring to buffer).
So, the problem of multiple reads, is that you have got read data in the reader (luggage on the carousel), that your code is gradually transferring them to the buffer (picking the luggage up).
In our example, if you don't like to collect all luggage, you can ask someone to take some of them, before they reach to you.
The below code does this. While you have data in the reader (the card is near to the reader), it transfers data from reader to buffer and then zeros all of them in the buffer:
First, place this code before "void setup()":
boolean multipleRead = false;
This defines a false/true variable to tell if this is the first time you are reading the tag (false), or it's being read multiple times (true).
Then, put this one at the end of the code block that shows the tag is fully read. If you are using Michael Schoeffler's library for your RDM6300/630 RFID, put it after "else if (ssvalue == 3) {":
multipleRead = true;
It change the variable to true, when your tag is read. That tells the program that your first read is done and the next upcoming read(s) would be "multiple read" and you don't want them.
Then put this at the end of the RFID reader code (if your RFID code is under void loop (), put the below code just after "void loop (){":
if (multipleRead) {
while (ssrfid.available() > 0) {
int ssvalue = ssrfid.read(); // read
if (ssvalue == -1) { // no data was read
break;
}
}
for (int x = 0; x < 14; x++)
{
buffer[x] = 0;
}
multipleRead = false;
}
It empties the reader and then zeros the buffer, while there is a card nearby. When you move the card away, multipleRead value would turn to false, which let another RFID reading loop to initiate.
Hope that helped :)
I guess what you want is a edge trigger instead of level trigger with time limit.
For example, you may prefer to read a RFID card when it firstly comes near to the antenna, once only; when it keeps to contact the antenna, still take no more actions. When you remove the card and place it again near to the antenna, the MCU starts to read the card again.
If so, the following code could be for your reference. What I have done is just to add 1 more flag to keep checking the card_status before checking if a RFID card comes near to the antenna.
int card_status = 0; //0:readable; 1:not-readable
if ( (Serial.available() > 0) && (card_status == 0) ) {
card_status = 1; //disable to read card after exit this loop
//your code, a card is near to the antenna, try to read it.
readVal = Serial.read();
if (readVal == 2) {
counter = 0; // start reading
} else if (readVal == 3) {
processTag();
clearSerial();
counter = -1;
} else if (counter >= 0) {
readData[counter] = readVal;
++counter;
}
}
reset the card status when no RFID signal comes in && card status is true,
if ( (!(Serial.available() > 0)) && (card_status == 1) ) {
card_status = 0; //enable to read card again
//no signal, no card is near to the antenna.
}
You can set a delay (e.g. delay(2000)) after reading the (end of tag). A delay of (say) 2 seconds will allow the user to move the card far enough away from the reader. Note that delay is a blocking command which might not suit your purposes, in which case you could be looking at using the millis count to activate/deactivate the Serial.read.
Another option is to accept the multiple reads, but keep a state of which card has been read. If the new card number is the same as the old card number (within a reasonable timeframe) then just ignore.

Cannot receive data more than once with 433Mhz on Arduino

I am currently building myself some lighting for my apartment using Arduinos and strips of WS2812b LEDs. My plan was to control them with an app from my smartphone and a Raspberry Pi. The phone sends data (like color, mode etc.) to the Pi and the Pi transmits that via a 433MHz transmitter to three Arduino Nanos I wanted to place across the room.
Sending data from my phone through the Pi to the Arduinos works without a problem, the data is received correctly and the LEDs light up, but as soon as I do this once no more data can be received. There is no issue when I just receive and don't do anything else.
Here's my code:
#include <RCSwitch.h>
#include <Adafruit_NeoPixel.h>
#define LEDPIN 9
#define NUMPIXELS 75
#define STARTBIT 4194305
#define STOPBIT 8388609
#define SETBIT 2097153
RCSwitch rc = RCSwitch();
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
uint32_t data[] = {0,0,0};
bool written[] = {false, false, false};
bool led_set = false;
uint32_t wait = 0;
uint16_t j = 0;
int index = 0;
bool recording = false;
int led = 0;
unsigned long time;
static unsigned long received = 0;
void setup() {
Serial.begin(9600);
time = millis();
pinMode(LEDPIN, INPUT);
rc.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
strip.begin();
for (int i = 0; i < 75; i++) {
strip.setPixelColor(i, strip.Color(255,255,255));
}
strip.show();
}
void loop() {
if (millis()-time >= 1000) {
Serial.println(*((unsigned int*)rc.nReceivedValue));
Serial.println(rc.nReceivedValue);
Serial.println(millis());
time = millis();
}
if (rc.available()) {
received = rc.getReceivedValue();
rc.resetAvailable();
Serial.print("received: ");
Serial.print(received);
Serial.println();
}
if ((received == STOPBIT) && recording) {
Serial.println("stopped");
recording = false;
}
else if ((received == STARTBIT) && not recording) {
recording = true;
led_set = false;
Serial.println("started");
}
if (recording) {
if(received == SETBIT && written[index] && index < 3) {
index++;
Serial.println("setbit");
}
else if(received != STARTBIT && received != STOPBIT && received != SETBIT && received != 0 && not written[index] && index < 3) {
data[index] = received & 0xFFFFFFFF;
written[index] = true;
//Serial.println(received);
Serial.println(data[index]);
Serial.println("written");
}
}
else if (data[0] != 0 && data[1] != 0 && data[2] != 0 && not recording && not led_set) {
Serial.println("setting LED");
for (int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, data[2]);
}
strip.show();
rc.resetAvailable();
}
if (not recording) {
for (int k = 0; k < 3; k++) {
written[k] = false;
}
index = 0;
}
}
(I pretty much ripped this code to pieces and this is what's left.)
These are the transmitter/receivers and I use RC-Switch and Adafruit NeoPixel as libraries, other LED-libraries (FastLED, light_ws2812) had the same error though.
What I found out so far is that it works with less than 5 LEDs and sometimes with more if I set the colors to low values. Then it's more or less chance if I get another receive or not. If I do not set the LEDs here
else if (data[0] != 0 && data[1] != 0 && data[2] != 0 && not recording && not led_set) {
Serial.println("setting LED");
for (int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, data[2]);
}
strip.show();
I can receive more data, if I hardcode the values for the colors it works only for bright white (so every color to 255) or for color values below 14.
If I comment out the last four lines in setup() the problem can't even be solved by the restart button (unplugging helps though). Switching the receiver does not work either.
All three of the Arduinos I use have the same issue.
I use a 6A power supply (at least for the strip with 75 LEDs, the other two have 30 LEDs each with a 2.4A supply) so power should be no issue.
When I hooked up my Arduino Uno to the second data pin of the receiver it couldn't receive anything either, using the Uno with another receiver next to it was fine. Using the Uno as oscilloscope and displaying the voltage on the data pin I noticed a lot of noise after first transmitting. It looked like it increased with the color values. The noise was gone after I restarted the Arduino with the LED-setting in setup() and it doesn't occur if I don't do anything with the LEDs at all. There is a 5 MOhm pull-down resistor between data and GND on the receiver module. I don't actually know if this noise has anything to do with this, because receiving was sometimes fine even with noise.
I tried disabling the receive pin before setting the LEDs and enabling it afterwards but that didn't help. Enabling interrupts manually doesn't do anything either. I changed the rc-switch interrupt handling so it prints something every time an interrupt occurs. That worked even after receiving the first data, The Arduino somehow just doesn't recognize what's been sent.
I really would like to know if there's anything I could try to solve this, besides switching to WiFi-modules or actual wire.

xbee pro s2b receiving random data

I have a trouble with xbee s2b.
I try to receive two joystick values using only xbee placed on sparkfun regulated board (Coordinator API) and process these data on Arduino Uno connected to other xbee s2b placed on explorer board.(Router API). I configured xbees using X-CTU properly and I adjusted DIO0 and DIO1 to ADC[2] on Router Xbee. There is no problem when working with one joystick. But when I try to receive two joystick values at the same time, they are not working correctly. When I look the incoming data on serial monitor, I see;
https://lh3.googleusercontent.com/-20vjr0EchsQ/VqyZXgq84VI/AAAAAAAAA_0/WhEtoOU61vA/s1280-Ic42/Screenshot_3.jpg
My Arduino code is:
int packet[32];
void setup()
{
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
if (Serial.read() == 0x7E) {
packet[0] = 0x7E; //start delimiter
packet[1] = readByte(); //MSB1
packet[2] = readByte(); //MSB2
int dataLength = (packet[1] << 8) | packet[2]; //between the length and the checksum
printPacket(dataLength+4);
Serial.println("");
}
}
delay(1000);
}
void printPacket(int k) {
for(int i=0; i < k; i++) {
Serial.print(packet, HEX);
Serial.print(" ");
delay(1000);
}
}
int readByte() {
while (true) {
if (Serial.available() > 0) {
return Serial.read();
}
}
}
What is the point I missed? Can you help me about this issue. Thank you in advance.
The delay(1000) statements may be causing you to lose characters from your serial buffer, and might not be necessary.
The code you shared appears incomplete. Where are you reading the dataLength bytes of the packet? How does printPacket() print the bytes?
Your inbound packet buffer should be larger -- I think the XBee S2B can have network payloads of up to 255 characters, in addition to the frame header and checksum.
You've created a blocking readByte() call, which isn't good program design. Consider something like this instead:
unsigned char packet[300];
int packet_index = 0;
int packet_length;
void loop() {
while (Serial.available() > 0) {
packet[packet_index++] = Serial.read();
if (packet_index == 3) {
packet_length = (packet[1] << 8) | packet[2];
}
if (packet_index > 2 && packet_index == packet_length) {
print_packet();
packet_index = 0;
}
}
}
void print_packet() {
int i;
for (i = 0; i < packet_length; ++i) {
Serial.print(packet[i], HEX);
Serial.print(" ");
}
Serial.println("");
}
If you have too much data to print and you're overflowing your outbound serial buffer, try increasing the speed of the console's serial port to 115200bps. Or print the bytes as you receive them instead of waiting until the packet is complete.

Resources