Receiving whole string in uart sending data - arduino

I connect my NodeMCU to Arduino Uno. The goal is to receive the whole string for example "12", every 1 sec.
This is my code on Arduino Uno side ( the sender)
int mock = 0;
void setup() {
Serial.begin(115200);
s.begin(115200);
}
void loop() {
//Write mock to NodeMCU
s.print((int)mock,DEC);
s.println();
mock++;
delay(1000);
}
On NodeMCU side ( the receiver)
char data; //Initialized variable to store recieved data
String line;
void setup() {
Serial.begin(115200);
s.begin(115200);
while (!Serial) {
;
}
}
void loop() {
if( s.available() >= 2) {
for (int i = 0; i< 2; i++ ) {
data = s.read();
line += data;
}
delay(1000);
}
Serial.print(line);
}
But the result on the serial panel is not what I expected
[![Serial terminal][1]][1]
https://i.stack.imgur.com/NGC3k.png
How can I make it so that I can receive something like
12
(wait one sec)
13
(wait one sec)
....
Node MCU just prints the whole thing, I can't delay it.

Related

How to control the display and non-display of sensor values ​in Arduino using Bluetooth?

I have a sensor that connects to the body and displays muscle signals.
In the setup guide of this sensor, it is said to upload the following code on Arduino, and when we open the Serial Monitor, the sensor values start to be displayed.
Now I want to control the display of these signals using Bluetooth.
So that when I click on the start button in my App, Serial.print() will start working. Also, when I click on the Stop button, the display of these signals and numbers will stop.
Sensor setup guide is this :
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(analogRead(A0));
}
And this is how it works properly :
But when I upload a piece of code that I wrote to my Arduino, it only shows me just on value.
this is my code :
#include <SoftwareSerial.h>
SoftwareSerial BTserial(0, 1); // RX | TX
char Incoming_value = 0;
void setup() {
Serial.begin(9600);
BTserial.begin(9600);
}
void loop() {
Incoming_value = Serial.read(); // "1" is for Start
if (Incoming_value == '1') {
Serial.println(Incoming_value);
StartSensor();
}
}
int StartSensor() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(200);
}
also please tell me How to write StopSensor Function for Stop print Sensor Value.
Try this code first (Without Bluetooth module)
#include <SoftwareSerial.h>
SoftwareSerial BTserial(0, 1); // RX | TX
char Incoming_value = 0;
int state = 0;
void setup() {
Serial.begin(9600);
//BTserial.begin(9600);
}
void loop() {
Incoming_value = Serial.read(); // "1" is for Start
if (Incoming_value == '1') {
state = 1;
}
else if (Incoming_value == '0') {
state = 0;
}
if (state == 1) {
StartSensor();
} else {
Serial.println(0);
}
}
int StartSensor() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(200);
}

Sending two arrays to Arduino from Processing

I'm trying to pass multiple variables (n number of strings and n number of ints) from processing to my Arduino. I found this tutorial online and managed to send a single value. Now I have two arrays that both need to be accessed by the Arduino filesTypes[] and filesSizes[]. filesTypes[] consists of a 3 char long strings while fileSizes[] is an array of different integers.
Here is my Processing code:
import processing.serial.*;
Serial myPort; // Create object from Serial class
String[] fileTypes;
int[] fileSizes;
String[][] lines;
void setup()
{
size(200,200); //make our canvas 200 x 200 pixels big
String portName = Serial.list()[1]; //change the 0 to a 1 or 2 etc. to
match your port
myPort = new Serial(this, portName, 9600);
launch( sketchPath("") + "/test.bat");
}
void draw() {
if (mousePressed == true)
{ //if we clicked in the window
txtToStrg();
myPort.write('1'); //send a 1
txtToStrg();
} else
{ //otherwise
myPort.write('0'); //send a 0
}
}
void txtToStrg(){
String[] lines = loadStrings("list.txt");
fileTypes = new String[lines.length];
fileSizes = new int[lines.length];
for (int i = 0 ; i < lines.length; i++) {
if(lines[i] != null) {
String[] splitLine = split(lines[i], ' ');
fileTypes[i] = splitLine[0];
fileSizes[i] = int(splitLine[1]);
println(fileTypes[i] + " = " + fileSizes[i]);
}
}
}
And here my Arduino code:
char val; // Data received from the serial port
int ledPin = 4 ; // Set the pin to digital I/O 13
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if (val == '1')
{ // If 1 was received
digitalWrite(ledPin, HIGH); // turn the LED on
} else {
digitalWrite(ledPin, LOW); // otherwise turn it off
Serial.print(val);
}
delay(10); // Wait 10 milliseconds for next reading
}
If a pass anything but a char it stops working.

PIC16F628A to Arduino RF Communication Fails (433MHz)

I have pic16f628a and Arduino UNO...
I use MikroC for PIC...
I use 433 mhz transmitter and receiver.
My purpose is reading datas from Arduino UNO which I send from PIC16F628A; but I couldn't success it...
The circuit of PIC16F628A (Transmitter):
The circuit of Transmitter
I connected first pin of receiver to +5V of Arduino;
second pin of receiver to 12.pin of Arduino,
last pin of receiver to GND pin of Arduino.
Transmitter(PIC16F628A):
char pre[15]={'U','U','U','U','U',255,255,255,255,255,0,0,0,0,0}; //start bytes...
char ileri[3]={'f','r','w'};
char geri[3]={'b','c','k'};
char dur[3]={'d', 'u', 'r'};
char i=0,j=0;
void kurulum()
{
CMCON= 7;
TRISB= 2;
UART1_Init(2400);
delay_ms(100);
}
void main()
{
kurulum();
while(1)
{
for(i=0;i<15;i++)
{
UART1_Write(pre[i]);
}
for(j=0;j<10;j++)
{
for(i=0;i<3;i++)
{
while(!UART1_Tx_Idle());
UART1_Write(ileri[i]);
}
}
//*************************************************************
for(i=0;i<15;i++)
{
UART1_Write(pre[i]);
}
for(j=0;j<10;j++)
{
for(i=0;i<3;i++)
{
while(!UART1_Tx_Idle());
UART1_Write(geri[i]);
}
}
for(i=0;i<15;i++)
{
UART1_Write(pre[i]);
}
for(j=0;j<10;j++)
{
for(i=0;i<3;i++)
{
while(!UART1_Tx_Idle());
UART1_Write(dur[i]);
}
}
}
}
Receiver (Arduino):
// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem#airspayce.com)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
#include <VirtualWire.h>
const int led_pin = 13;
const int receive_pin = 12;
void setup()
{
delay(1000);
Serial.begin(9600); // Debugging only
Serial.println("setup");
// Initialise the IO and ISR
vw_set_rx_pin(receive_pin);
//vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2400); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
pinMode(led_pin, OUTPUT);
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
digitalWrite(led_pin, HIGH); // Flash a light to show received good message
// Message with a good checksum received, dump it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(' ');
}
Serial.println();
digitalWrite(led_pin, LOW);
}
}
I tried this code; but it didn't work...
There is another code;
void setup() {
Serial.begin(2400);
}
void loop() {
if (Serial.available() > 0){
Serial.println(Serial.read());
}
}
Before trying it; I connected data pin of receiver to RX pin of Arduino...
I usually got '0' byte.i
It didn't work as I desired...
SOLVED
The tests I have done so far were already taking the true datas but I was viewing them as numbers...
That's why I couldn't understand that It was working well.
Let's have a look at codes;
Transmitter:
The same as transmitter code at question message
Arduino (Receiver):
char x, msg[6];
int i= 0;
void setup() {
Serial.begin(2400);
}
void loop() {
if (Serial.available() > 0){
msg[i] = Serial.read();
if (msg[0]=='f' || msg[0] == 'b' || msg[0] == 'd'){
i++;
}
if (i==3){
Serial.println(msg);
i = 0;
msg[0]=0;
}
}
}
msg[0]=='f' || msg[0] == 'b' || msg[0] == 'd'
The purpose of comparison above is catching "frw", "bck" or "dur" messages which I sent transmitter...
The data pin of the receiver should be connected RX pin of the Arduino...

Global variable arduino

I'm using I2C to communicate a Master Arduino to 4 Slaves Arduinos, and an Shield (OULIMEX Shield LCD 16x2) on every Arduino slave.
I send Data from the master to slaves using I2C. So I use this code in the master :
#include <Wire.h>
#include <math.h>
#include <floatToString.h>
double incomingData;
void setup()
{
Wire.begin();
Serial.begin(9600);
incomingData = Serial.parseFloat(); //read incoming data
}
void loop()
{
delay (1000);
if (Serial.available())
{
incomingData = Serial.parseFloat(); //read incoming data
Wire.beginTransmission(8); // transmit to device #8
if ((M==0) || (M==1) || (M==2))
Wire.beginTransmission(8); // transmit to device #8 *****************************************************************
else
Wire.beginTransmission(7); // transmit to device #7 *****************************************************************
M++;
if (M==5)
M=0;
String a = "";
a = floatToString(test,incomingData,3,5,true);
for(i=0; a[i]!='\0'; ++i); // length of the string
Wire.write(i);
Wire.write(floatToString(test,incomingData,3,5,true)); // sends one byte
Wire.endTransmission(); // stop transmitting
}
}
I wanted the Data to be printed on the Shield, but I'm connecting all slaves with the same way with the master. For that I have two problems :
1- The global data I'm using to print value is always printed as 0, and not giving the real value;
2- All Shields print the same thing : For exemple, I print "hello" in the first Shield, and I print "hi" in the second Shield, but bouth are printing the same thing (hello or hi).
The code using for the first slave is :
#include <LCD16x2.h>
#include <Wire.h>
LCD16x2 lcd;
int buttons;
int sensorPin = A0; // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
float numOut;
int comp=1 ;
String wordd = "";
int M =0;
void setup()
{
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop()
{
delay(500);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
wordd = "";
int x = Wire.read();
for (int i=0; i<=x; i++)
{
char c = Wire.read();
wordd += c;
}
numOut = wordd.toFloat();
Serial.println(numOut,3); // print the integer
}
Thank you in advance !!
I think it's due to a poor program structure in master shield.
This block selects the slave but on the first line you already select #8
I think this is confusing for the slaves.
Wire.beginTransmission(8); // transmit to device #8
if ((M==0) || (M==1) || (M==2))
Wire.beginTransmission(8); // transmit to device #8
else
Wire.beginTransmission(7); // transmit to device #7
This block should be at the end of the function
M++;
if (M==5)
M=0;
Then you parse the value in a string.
But leave out the first char because you write ++i instead of i++
Moreover you close the loop with ; so it does nothing
String a = "";
a = floatToString(test,incomingData,3,5,true);
for(i=0; a[i]!='\0'; ++i); // length of the string
Finally you write the ordinal number of the byte
And then again the Whole string
So you should get "0" (or "1" because of ++i)
followed by your number if Wire.write() supports it
Wire.write(i);
Wire.write(floatToString(test,incomingData,3,5,true)); // sends one byte
Wire.endTransmission(); // stop transmitting
}
Your sketch should be:
if (Serial.available())
{
incomingData = Serial.parseFloat(); //read incoming data
String a = "";
a = floatToString(test,incomingData,3,5,true);
if ((M==0) || (M==1) || (M==2))
Wire.beginTransmission(8); // transmit to device #8
else
Wire.beginTransmission(7); // transmit to device #7
for(i=0; a[i]!='\0'; ++i) // length of the string
Wire.write(a[i]); // write one byte
Wire.endTransmission(); // stop transmitting
M++;
if (M==5) M=0;
}
Let me know if this works.
I already ask this question but I think I have the answer of it. A global variable have to be diclared befor the void setup, and the void loop too, like that :
type YourGlobalVariable;
void setup()
{
}
void loop()
{
}
So, it is exactly how I did already. The reason it didn't work for me, it was cause of I used this function :
void receiveEvent(int howMany) {}
I don't really know what are the properties of it that let it not work for a global variables, but It works like I sayd already.
Thank you all

I2C between RPI and Arduino using Processing

Posted here is my code for my RPi master and Arduino slave project. I have an analog sensor connected to the Arduino and i am reading this data with Processing on the RPi. I am using Processing because I intend on generating a graph and waveform with the data. The code below seems to work, however, any slight movement of setup "disconnects" the slave device because I get the following message. "The device did not respond. Check the cabling and whether you are using the correct address." I have narrowed the problem down and found out that it always disconnects at the i2c.read();function. My question is whether there is some type of break function so that when this does happen processing moves on and tries again in the next iteration? Or if it is stuck in a loop is it waiting for some signal from the slave device? Does anyone have any suggestions on how to approach this?
Processing Code
import processing.io.*;
I2C i2c;
int val = 0;
void setup()
{
i2c = new I2C(I2C.list()[0]);
}
void draw ()
{
if (I2C.list() != null)
{
i2c.beginTransmission(0x04);
i2c.write(8);
byte[] in = i2c.read(1);
int accel = in[0];
println (accel);
}
}
Arduino Code
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
int number = 5;
int state = 0;
const int zInput = A0;
int zRawMin = 493;
int zRawMax = 530;
float acceleration;
int accel;
void setup() {
analogReference(EXTERNAL);
pinMode(13,OUTPUT);
Serial.begin(9600); // start serial for output
Wire.begin(SLAVE_ADDRESS); // join i2c bus with address #8
Wire.onReceive(receiveData); // register event
Wire.onRequest(sendData);
Serial.println ("Ready");
}
void loop() {
int zRaw = ReadAxis (zInput);
acceleration = map (float(zRaw), float (zRawMin), float(zRawMax), -9.81, 9.81);
accel = int(acceleration);
//delay(100);
}
void receiveData(int byteCount)
{
while (0 < Wire.available())
{ // loop through all but the last
number = Wire.read(); // receive byte as a character
//Serial.print("data received");
Serial.println(number); // print the character
if (number==1)
{
if (state == 0)
{
digitalWrite(13,HIGH);
state = 1;
}
else
{
digitalWrite(13,LOW);
state = 0;
}
}
}
}
void sendData()
{
Wire.write(accel);
}
int ReadAxis(int axisPin)
{
long reading = 0;
int raw = analogRead(axisPin);
return raw;
}
Looks like a solution might be to use a try/catch block courtesy of #Kevin Workman. It works well for what I need it to do thx.
here is the updated Processing code.
import processing.io.*;
I2C i2c;
int val = 0;
void setup()
{
i2c = new I2C(I2C.list()[0]);
}
void draw ()
{
if (I2C.list() != null)
{
i2c.beginTransmission(0x04);
i2c.write(8);
try
{
byte[] in = i2c.read(1);
}
catch(Exception e)
{
i2c.endTransmission();
}
int accel = in[0];
println (accel);
}
}

Resources