I've got the following function to make a conversion from a Hex String to a Byte array. Then, I calculate the Checksum:
private String CalcChecksum (String message) {
/**Get string's bytes*/
//byte[] bytes = DatatypeConverter.parseHexBinary(message.replaceAll("\\s","")).getBytes();
message = message.replaceAll("\\s","");
byte[] bytes = hexToByteArray(message);
byte b_checksum = 0;
for (int byte_index = 0; byte_index < bytes.length; byte_index++) {
b_checksum += bytes[byte_index];
}
int d_checksum = b_checksum; //Convert byte to int(2 byte)
int c2_checksum = 256 - d_checksum; //Hacer complemento a 2
String hexString = Integer.toHexString(c2_checksum); //Convertir el entero (decimal) a hexadecimal
return hexString;
}
public static byte[] hexToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
Making some test, for example for the hex value "e0", the hexToByteArray is getting the value "-32". So the final returning value in the CalcChecksum is "17a".
What I need is to get unsigned values in the hexToByteArray function. This is because i need to send the Checksum in a hexString to a MCU where the Checksum is calculated with unsigned values, so isntead of get the "-32" value, it gets "224" and the final hex value is "7a" instead of "17a".
i think that doing some kind of conversion like when the byte result is a negative value, do something like 255 + "negative value" + 1. This will convert "-32" into "224".
The problem is that i'm trying to do it, but i'm having some errors making the conversions between bytes, int, etc...
So, how could i do?
For the moment, I think that this can be the solution.
Just including in the CalcChecksum function the next code after int d_checksum = b_checksum;:
if (d_checksum < 0) {
d_checksum = 255 + d_checksum + 1;
}
Related
I want to convert my float variables into HEX value like 0x00466 or etc. but when I try all the things that I saw in the internet my Serial Console just turns out crazy :D like "' #gA".
I tried this code below
float gyrox, gyroy, gyroz, accelx, accely, accelz, enlem, boylam, sicaklik, yukseklik, basinc;
byte ByteArray[11];
void setup() {
Serial.begin(9600);
gyrox = 1.5;
gyroy = 2.5;
gyroz = 2.0;
accelx = 5.3;
accely = 3.2;
accelz = 6.1;
enlem = 39.9250506;
boylam = 32.8369756;
sicaklik = 35.0;
yukseklik = 103.0;
basinc = 65.31455;
ByteArray[0]=(gyrox,HEX);
ByteArray[1]=(gyroy,HEX);
ByteArray[2]=(gyroz,HEX);
ByteArray[3]=(accelx,HEX);
ByteArray[4]=(accely,HEX);
ByteArray[5]=(accelz,HEX);
ByteArray[6]=(enlem,HEX);
ByteArray[7]=(boylam,HEX);
ByteArray[8]=(sicaklik,HEX);
ByteArray[9]=(yukseklik,HEX);
ByteArray[10]=(basinc,HEX);
}
void loop() {
Serial.println((char*)ByteArray);
}
and the result is ""(:D) I want the result like "0x000466 or anything likte HEX value" so what should I do?
You can cast the float to an array of bytes to get its internal representation. Then you can loop over all of the bytes and print each of them individually.
void printFloat(float const f)
{
// cast the float to an array of bytes
uint8_t const * const byteArray = (uint8_t const *)&f;
// print the start
Serial.print("0x");
// loop over the bytes, sizeof(f) tells us how many bytes make up the float
for (size_t idx = 0; idx != sizeof(f); ++idx)
{
// get the byte for this position
uint8_t const b = byteArray[idx];
// print a zero if b < 16,
// https://stackoverflow.com/questions/19127945/how-to-serial-print-full-hexadecimal-bytes
Serial.print(b>>4, HEX);
Serial.print(b&0x0F,HEX);
}
}
A float is 32 bits long (4 bytes). You can try this:
float f;
Serial.print("0x"); Serial.print(*(uint32_t*)&f, HEX);
If you really need leading zeroes, try this:
void hex_print(uint32_t x)
{
Serial.print("0x");
for (uint32_t mask = 0x0FFFFFFFul; mask && mask > x; mask >>= 4)
Serial.print('0');
Serial.print(x, HEX);
}
// calling as:
float f = 123.456f;
hex_print(*(uint32_t*)&f);
I'm trying to convert a string to an integer (which is actually a binary number) so that I can output the DEC value, but where the answer SHOULD be 63 (00111111), it's giving me -19961 as an output? It would be great if someone can help me correctly convert the string to an int :)
// C++ code
//
const int button = 13;
int buttonPressed = 0;
int counter = 0;
int myInts[] = {0, 0, 1, 1, 1, 1, 1, 1};
void setup()
{
Serial.begin(9600);
pinMode(button, INPUT);
}
void loop()
{
buttonPressed = digitalRead(button);
if (buttonPressed == HIGH){
counter = count();
//rial.println(counter);
}
else{
Serial.println("Button not pressed");
}
delay(1000);
}
int count()
{
String myString = ""; //Empty string for constructing
int add = 0;
int i = 0;
//Should add all the values from myInts[] into a string
while(i < 8){
myString = String(myString + myInts[i]);
Serial.println(add);
delay(1000);
add++;
i++;
}
Serial.println(myString);
int myNumber = myString.toInt(); //Convert the string to int
Serial.println(myNumber, DEC); //Should print 63 in this case
return add;
}
Your code currently does the following:
Concatenates all your integers together to make a string "00111111"
Attempts to convert it (as a string holding a base 10 integer) to the integer 111,111 (one hundred eleven thousand, one hundred eleven)
Hits integer overflow. The range of an Arduino int is -32768 to 32767 (65536 possible values), so the number you really have is 111111 - 2*65536 = -19961.
I don't believe that there's an overload of Arduino's ToInt that converts a binary string to an integer. Depending on the C++ support in Arduino, you may be able to use std::stoi as described here.
Instead, you may choose to do the conversion yourself - you can keep track of a number sum, and at each loop iteration, double it and then add the next bit:
int sum = 0;
for(int i = 0; i < 8; i++) {
sum *= 2;
sum += myInts[i];
// print and delay if you want
}
Over the eight iterations, sum ought to have values 0, 0, 1, 3, 7, 15, 31, and finally 63
I have an arudino code where I get some temperature reading:
double c1 = device.readCelsius();
Serial.println(c1);
The output is for example: 26.23
What I need is to get this converted to 2623 and then to HEX value so I get: 0x0A3F
Any clue?
I guess your float values always get numbers up to two decimal. So, you can just multiply the value which you read from sensor with a 100.
decimalValue = 100 * c1
And then you can use this small code for converting the decimal value to HEX.
Thanks to GeeksforGeeks
You can find the full tutorial here
// C++ program to convert a decimal
// number to hexadecimal number
#include <iostream>
using namespace std;
// function to convert decimal to hexadecimal
void decToHexa(int n)
{
// char array to store hexadecimal number
char hexaDeciNum[100];
// counter for hexadecimal number array
int i = 0;
while (n != 0) {
// temporary variable to store remainder
int temp = 0;
// storing remainder in temp variable.
temp = n % 16;
// check if temp < 10
if (temp < 10) {
hexaDeciNum[i] = temp + 48;
i++;
}
else {
hexaDeciNum[i] = temp + 55;
i++;
}
n = n / 16;
}
// printing hexadecimal number array in reverse order
for (int j = i - 1; j >= 0; j--)
cout << hexaDeciNum[j];
}
// Driver program to test above function
int main()
{
int n = 2545;
decToHexa(n);
return 0;
}
I have a string in arduino
String name="apple orange banana";
Is it possible to store each item in an array arr
so that
arr[0]="apple"
arr[1]="orange" ......etc
if not store them in individual variables?
How to split a string using a specific delimiter in Arduino? I believe this would help you, you could do a while loop like:
int x;
String words[3];
while(getValue(name, ' ', x) != NULL){
words[x] = getValue(name, ' ', x);
}
Using this function:
// https://stackoverflow.com/questions/9072320/split-string-into-string-array
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
If you know your list length and the max characters per list item, you could do
char arr[3][6] = {"apple", "orange", banana"};
edit: if you are looking for something like String arr[3] you aren't going to get it because of how memory is managed with the C language
My question will be Arduino specific, I wrote a code that turns array of characters (text) into binary string, but the problem is that the binary representation is not 8 bits, its sometimes 7 bits, 6 bits or even 1 bit representation (if you have a value of 1 as decimal). I'm using String constructor String(letter, BIN) to store the binary representation of letter in a string.
I would like to have a 8 bits representation or even a 7 bits representation.
String text = "meet me in university";
String inbits;
byte after;
byte bits[8];
byte x;
char changed_char;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Press anything to begin");
inbits = convertToBits(text);
}
String convertToBits(String plaintext)
{
String total,temp;
total = String(plaintext[0],BIN);
total = String(total + " ");
for (int i=1;i<plaintext.length();i++)
{
temp = String (plaintext[i],BIN);
total = String(total + temp);
total = String(total + " ");
}
Serial.println(total);
return total;
}
If the length of the argument string is less then 8, prepend "0"s until it is 8 bits long.
You could do something similar to the following:
void PrintBinary(const std::string& test)
{
for (int c = 0; c < test.length(); c++)
{
unsigned bits = (unsigned)test[c];
for (int i = 0; i < 8; i++)
{
std::cout << ((bits >> (7 - i)) & 1U);
}
std::cout << " ";
}
}
Modifying the above example to use String and Serial.println instead of std::string and std::cout should be trivial. I don't own an arduino to test with so I couldn't modify your code and test if the above is possible in the environment you work in but I assume it is.
PrintBinary("Hello"); //Output: 01001000 01100101 01101100 01101100 01101111
String(letter, BIN) doesn't zero pad the string. You have to do it yourself.
You need to prepend the 0 character until your binary string is 8 characters long.
String convertToBits(String plaintext)
{
String total, temp;
total = "";
for (int i=0; i<plaintext.length(); i++)
{
temp = String (plaintext[i], BIN);
while (temp.length() < 8)
temp = '0' + temp;
if (i > 0)
total = String(total + " ");
total = String(total + temp);
}
Serial.println(total);
return total;
}