Convert ASCII to Int - arduino

I'm using an Arduino for a project that involves controlling a servo via the serial monitor. The Arduino was receiving different values than what I entered. I'm sure that this is because serial data is read as ASCII. Is there any way that I could convert it to Int? Thanks!

I assume by Arduino you mean "Arduino IDE (C++)".
Arduino has a toInt() function.
int asciiVal = 97;
String mystr = (char)asciiVal;
Serial.println(mystr); //prints a
Serial.println(mystr.toInt()); //prints 97
Explained here: https://www.arduino.cc/en/Tutorial/StringToIntExample

Do it like this:
string input = Serial.readString();
int angle = int(input);
As I answered here.

Related

Cut out part of the data shown in serial monitor of Arduino

I'm new member here and also a joiner in programming
i try to extract information from my vehicle using OBD-II cable adapter. I try simple code to read the RPM and successfully got it and print it in serial monitor but i face a simple problem. Serial monitor display the PID-Code + current value of RPM as shown below:
010C849 where 010C: refer to RPM-PID used and 849: current value of RPM
so can i cutout the HEX number from the result and just display the value of RPM such as (849)
i used the following code:
Here is an example of the result `
#include <OBD2UART.h>
COBD obd;
void setup()
{
pinMode(13, OUTPUT);
obd.begin();
while (!obd.init());
}
void loop()
{
int value;
if (obd.readPID(PID_RPM, value)) {
Serial.println(value);
delay(1000);
}
}
`
You could use Regex, to cut out a pattern, but Arduino (and, in general, C++) does not provide support for regular expression parsing.
Once you have the string, you can use indexOf() and substring() to extract substrings. Once you have a substring, you can use toCharArray() to extract the character array, and atoi() to convert that to an integer.
Once you have integer values you can print them out.

How to send and receive correctly more than one sensor's data via serial communication

I'm trying to send data of 2 sensors from arduino uno to NodeMCU V3 via serial communication,
when I try to send data from one sensor at the time everything works fine but when I use both it gives me random values
This is the arduino sender code :
int water_sensor_pin = 8;
void setup()
{ pinMode(water_sensor_pin, INPUT);
Serial.begin(115200);
}
void loop()
{
// First sensor
int soil_moisture=analogRead(A0);
int output_value = map(soil_moisture,430,70,0,100);
Serial.write(output_value);
// Second sensor
int value = digitalRead(water_sensor_pin);
if(value==HIGH){
Serial.write('1');}
if(value==LOW){
Serial.write('0');}
}
and this is the receiver's part of code
char msg[10];
.
.
.
if(Serial.available()>0){
// First sensor
int output_value = Serial.read();
Serial.println(output_value );
// Second sensor
char value = Serial.read();
Serial.println(value);
}
I expect the output to be correct values for both sensors
When using Serial in Arduino, you have to take care of sending a known amount of bytes and then read this amount of bytes.
On the transmitting side try something like Serial.write(output_value,4); in order to send four bytes and, on the receiving side, Serial.readBytes(output_value,4); in order to read the four bytes you sent, and only them.
Of course you can apply the same technic for the second value you want to send except that you may need only one byte as you seem to send a boolean.
Hope it helps!
EDIT
The technic above would work if you had a buffer of bytes to send. Unfortunately you have an integer value… So you can either try to:
convert your value as an array of char of a known size,
use the fact that the value you are trying to send can fit in a single byte and thus declaring it as a byte instead of an int and then reading this single byte on the receiver side.

Type casting operation

I am using NodeMCU & Energy meter. Energy meter is Modbus RTU device which display parameter in 32 bit. With below piece of code I could able to read the data from slave but need method to type cast from into 32 bit floating & display
When I change the value to unsigned decimal in ModScan software the values showing properly. But I need to display value in 32 bit floating point.
#include <ModbusMaster232.h>
#include <SoftwareSerial.h>
float data[100];
ModbusMaster232 node(1);
// Define one address for reading
#define address 1
// Define the number of bits to read
#define bitQty 70
void setup()
{
Serial.begin(9600);
// Initialize Modbus communication baud rate
node.begin(9600);
}
void loop()
{
int result = node.readHoldingRegisters(address, bitQty);
data[0] = (float)node.getResponseBuffer(0);
data[1] = (float)node.getResponseBuffer(1);
data[2] = (float)node.getResponseBuffer(2);
data[3] = (float)node.getResponseBuffer(3);
data[4] = (float)node.getResponseBuffer(4);
data[5] = (float)node.getResponseBuffer(5);
for (int i = 0; i < 100; i++)
{
//data[i] = node.getResponseBuffer(i);
Serial.println(data[i]);
}
Serial.println("............");
}
I would like to display the reading as shown in Modbus with type casting.
Actual Modbus device output from salve:
Arduino output while read data from energy meter:
You are casting a 16-bit word into a float. Check the slave documentation to find how they map a 32-bit floating point into two Modbus registers. Basically you need to know where the least significant word is (first or second register), load them into memory (shift if necessary) and cast to float.
I am looking and trying to solve exact same problem (with same results). This may help:
function read() {
client.readHoldingRegisters(0000, 12)
.then(function(d) {
var floatA = d.buffer.readFloatBE(0);
console.log("Total kWh: ", floatA); })
.catch(function(e) {
console.log(e.message); })
.then(close);
}
This is NodeJS and javascript version, which works and Arduino does not. Complete example can be found here and it works on Raspberry Pi https://github.com/yaacov/node-modbus-serial/blob/master/examples/buffer.js

Reading char sent from wireless transmitter and creating switch case

I'm trying to transmit a char wirelessly and have the receiver read that char through serial in order to create a switch statement.
When trying to convert into int, I get the same int value no matter what char I type into the html text box. Serial.print(buffer); is displaying the right char. All help appreciated.
This is the char I'm inputting, and the result in the serial
Let's try this way. After convert "buffer" from "char"-->"int".You can check if h is digital or not before doing something.
//..Your code..//
//..Your code..//
//..Your code..//
int h = (int)buffer;
if (isDigit(h))
{
//Do something;
}

Onewire temperatures to MQTT broker server

I am trying to modify the code from the example included in the onewire library for arduino so that no matter how many onewire devices I have plugged it will always find them and publish it to a MQTT using the device ID and the current temperature. I have gotten it to publish the temperature, but am having trouble adding the device ID or ROM which is in HEX to my topic.
So for example i want it to appear like this. Note the topic and msg for MQTT need to be Char* (more info here: http://knolleary.net/arduino-client-for-mqtt/api/#publish1)
topic = Celsius eg 12.09
payload (or msg) = \home[ROM]\temperature\current eg. \home\2894AA6220025\temperature\current
(just an example of the output you normally get when you run the code without my additions, this is the serial output!! notice the ROM and celsius that I want to use)
Have put my full code here, it is just a modification of the included onewire example with the pubsub MQTT part added on.
(see line 155 onwards) https://gist.github.com/matbor/5931466
//publish the temp now to mqtt topic
String strTopic = "/house/285A9282300F1/temperature/current"; // need to replace the 285A9282300F1 with the ROM ID on each LOOP!
char charMsg[10];
String strMsg = dtostrf(celsius, 4, 2, charMsg); //convert celsius to char
char charTopic[strTopic.length() + 1];
//char charMsg[strMsg.length() + 1];
strTopic.toCharArray(charTopic, sizeof(charTopic));
strMsg.toCharArray(charMsg, sizeof(charMsg));
client.publish(charTopic,charMsg);
Add this to the top of your sketch, outside of the loop function:
char hexChars[] = "0123456789ABCDEF";
#define HEX_MSB(v) hexChars[(v & 0xf0) >> 4]
#define HEX_LSB(v) hexChars[v & 0x0f]
This defines a pair of macros that return the most-significant and least-significant bytes of an int as the appropriate HEX character. (There may be more appropriate built-in's for this, but this is what I use out of habit).
The following code will insert the ROM, as a HEX string, into the topic. Note you can create the topic as a char[] directly - you don't need to go via a String object.
char charTopic[] = "/house/XXXXXXXXXXXXXXXX/temperature/current";
for (i = 0; i < 8; i++) {
charTopic[7+i*2] = HEX_MSB(addr[i]);
charTopic[8+i*2] = HEX_LSB(addr[i]);
}
For the payload, I'm not sure if it is 100% necessary, but I always explicitly initialise any char[] to all 0's when using as a buffer. This ensures whatever is written into the buffer will definitely be null-terminated. Again, you don't need to go via String types:
char charMsg[10];
memset(charMsg,'\0',10);
dtostrf(celsius, 4, 2, charMsg);
Finally, publish the message:
client.publish(charTopic,charMsg);

Resources