14

In a typical C++ program, you would use the typeid operator, like this: std::cout << typeid(myVar).name(); However, that requires a compiler feature called Runtime Type Information (RTTI). It's disabled in the Arduino IDE, presumably because it tends to increase the runtime memory requirements of the program. You can get more information about the ...


10

I use a simple stupid approach... void types(String a){Serial.println("it's a String");} void types(int a) {Serial.println("it's an int");} void types(char* a) {Serial.println("it's a char*");} void types(float a) {Serial.println("it's a float");} This is the concept of polymorphism where multiple functions with different parameter types are created but ...


10

The ATmega328 used in a lot of Arduinos is a 8-bit microcontroller. This means that registers are 8-bits, the data bus is 8-bits, the ports are 8-bits. There are some minimal 16-bit aspects to the system (e.g. one of the timers), but nearly everything is 8-bits. Therefore, most operations handle 8-bits at a time. Working on anything except 8-bits (i.e. 16-...


8

Whenever you write an equation in C/C++, the data types being operated on have a very real effect on the equation's output. Each type like int, float, and unsigned long have different behaviors, and take a certain amount of space in memory to store. int (on arduino) is store in 16 bits, with half of its values being given to negative numbers, half-1 ...


7

I think that the two most used libraries are the Adafruit RTClib and the pjrc.com TimeLib. They both have functions to convert the epoch, and they both are reliable. But both lack the timezone and the DaylightSavingTime. I think you find the pjrc.com TimeLib just slightly more suitable to handle the epoch time (which is a 32-bit unsigned long defined as '...


7

The problem is that float numbers are seldom an exact representation. So the float is stored as the closest number that is exactly representable as a float, namely 10446438 × 2−18 = 39.84999847412109375. When you multiply this by 100, you get 16322559 × 2−12 = 3984.999755859375. And than casting to an int or long results in 3984, not 3985. so whenever you ...


6

Once again an example to Why should I learn C/C++ first before learning Arduino. The main point here is: know your data types. Your calculation millisec*frequency/1000 would work if it was a compile time constant that is evaluated by the pre processor. In any other case this is a runtime value and so the limitations of the datatype apply. Unless stated ...


6

Any more sophisticated byte exchange can be done with binary operators. Extracting information You'll need some constants like MASK SHIFT 0xFF000000 24 (first byte, most significant) 0x00FF0000 16 (second byte) 0x0000FF00 8 (third byte) 0x000000FF 0 (last byte, least significant)...


5

Try unsigned char z[100]; IP.getBytes(z, 100); z[IP.length()] = 0; int n = atoi(z); To retrieve bytes inside the string. This assumes IP string's length is shorter than 100.


5

You need 2 typecasts. So atan(-ax/sqrt((float)ay*ay+(float)az*az)); Otherwise it will use int16_t for the right side of the addition and overflow. Though for speed you might want to typecast them as long (int32_t), as floats calculations on the arduino are really slow. The sqrt function will covert this double into a float for you.


5

Yes, it just blindly chops off the upper 16 bits. That means that the sign can change between the two. For instance, 123456789 gets truncated to -13035 and -123456789 truncates to 13035. To see that in more detail, look at the binary. 123456789 in binary is: 0000 0111 0101 1011 1100 1101 0001 0101 Truncate that at 16 bits and you get: 1100 1101 0001 ...


5

300 and 1000 are integers. What long V2 = (300 * 1000)/30000; really does is take the integers 300 and 1000 multiply them. This calculation overflows, and equals -27680. Dividing that by 30000 yields 0. What you added in your comment isn't a hack, it's the proper solution. By including the suffix L or UL you tell the compiler that you want longs, not ...


5

"Arduino": char, int, long; byte, word, unsigned long inttypes: int8_t, int16_t, int32_t; uint8_t, uint16_t, uint32_t A better classification would be: C and C++: char, int, long, unsigned long "Arduino": byte, word inttypes: int8_t, int16_t, int32_t; uint8_t, uint16_t, uint32_t I generally avoid the Arduino-specific types, as they are quite non-...


4

I need a sample rate of 6 kHz OK, so that means you need to sample and send every 1/6000 seconds (167 µs). I have a lengthy discussion about the ADC hardware. Amongst other things is a table of conversion times for the different ADC prescalers, assuming a 16 MHz clock: Prescaler 2 * 13 * 1/16E6 = 0.000001625 ( 1.625 µs) 4 * 13 * 1/16E6 = ...


4

Arduino String class provides method c_str(). So you don't have to convert it to C string, as it's already stored as a C string internally. And as mentioned in comments, the second parameter of strtoul is: endptr Reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value. ...


4

To illustrate the reasons better let's look at the actual content of the data. 0x80 is 0b10000000 in binary. A char is a signed variable, which means that the most significant bit is the sign bit, with two's complement representation So in 8-bit signed representation the value 0b10000000 is a sign bit and zero value - which is -128 in decimal notation, ...


4

This question is not really about the Arduino. It is about GNU C/C++ compiler optimizations. By adding the keyword const the compiler can do a lot of optimization. One is that the value does not need to be stored in SRAM. The value can end up as part of an instruction, become part of an expression that is evaluated at compile-time, etc. In the Arduino-...


4

In response to your answer: why don't you think it is convenient? As you already noticed, you can use the enum values directly in your sketch. Anyway, it is better to use a switch statement: Serial.write("ODB State: "); switch (odb.getState()) { case ODB_DISCONNECTED: Serial.write("Disconnected"); break; case OBD_CONNECTING: Serial.write("...


4

You already know, from previous answers, why the comparison doesn't give you the result you expect: you assumed that any multiple of 0.1 is also a multiple of 0.001, which is true for real numbers but nor for floats. To fix the issue, it has been suggested to you to allow for some fussiness in the comparison. I would suggest a different approach: keep your ...


4

unsigned long onPeriod = 60ul * 1000; ul makes 60 to unsigned long and then the calculation has place for result. without ul the constants and the result are int and it overflows


4

Okay, I figured out... this two prints the right number: sprintf(dt,"%llu", t); snprintf(dt, 18, "%llu", t);


4

irsend.sendNEC(strtoul(irrequest.c_str(), NULL, 10)); did the trick with the help of Juraj. Much thanks! I only had the set 10 to 16 to get it to work. Working code: // Configuration const char* CONFIG_SSID = "mywifi"; const char* CONFIG_PSK = "wifipassword"; const int CONFIG_SERIAL = 115200; const int CONFIG_PORT = 80; const int ...


3

It's passed as a char*. This can be derived from either a string literal (e.g. "212555121") or from a String via its c_str() method.


3

I tried the code below and it worked for me, don't miss the delay() part: Sender Code: void setup() { Serial.begin(9600); } void loop() { float yaw = 10.5; float pitch = 20.15; float roll = 100.10; float ypr[3]; ypr[0] = yaw; ypr[1] = pitch; ypr[2] = roll; Serial.write((byte*) ypr, 12); // No new-line delay(1000); ...


3

@mpflaga's answer gives a great alternative, but I thought I'd explain why your code works (grossly simplified). All the reinterpret cast does is let the compiler know how wide of a variable it assumes is in each element of the array. When you access data[1], it uses one byte at an offset of one byte from data[0]. When you cast to uint32_t and access ...


3

I prefer to use unions. example: union fourbyte { uint32_t dword; uint16_t word[2]; uint8_t byte[4]; }; union fourbyte val; val.dword = 0x03020100; Serial.println(val.byte[0], HEX); Serial.println(val.byte[1], HEX); Serial.println(val.byte[2], HEX); Serial.println(val.byte[3], HEX); Serial.println(val.word[0], HEX); Serial.println(val.word[1], ...


3

You can choose to treat the byte array as a float array by typecasting. Your attempt isn't far from a solution: ((float *)data.data)[0] = lon; // uses data.data[0] ... data.data[3] ((float *)data.data)[1] = lat; // uses data.data[4] ... data.data[7] When printing you should also treat the data array as float array: Serial.println(((float *)data.data)[0]); ...


3

One important fact about C and C++ languages is that their respective standards do not define the size (in bytes) of integral and floating point number types. They just define minimal ranges and relation between these ranges, e.g. range(short) <= range(int) < range(long) So the size of e.g. an int will typically depend on: the target platform (...


3

freq * long, since they are both integers, are calculated as integers. 440*256=112640 - in binary that is 1 1011 1000 0000 0000 and trimmed to 16 bits becomes 1011 1000 0000 0000 which is -18432 and that is where the heart of your problem is. Unless you explicitly say otherwise the Arduino's compiler does all calculations (except floating point) as 16-bit ...


Only top voted, non community-wiki answers of a minimum length are eligible