Esp32 and JsonArduino library reading analog Values in a Array - json

I'm trying to understand how to use Json with the ESP32 or Arduino.
In the following code example the idea is to read the values from a potentiometer and display it on the Serial Monitor. I was expecting to see something like this when I am turning the potentiometer.
"Reading: 0,54,140,175,480,782"
"Reading: 600,523,320,175,48,2"
But I get this
"Reading: 54,54,54,54,54,54"
"Reading: 140,140,140,140,140,140"
#include <ArduinoJson.h>
void setup() {
Serial.begin(9600);
}
void loop() {
StaticJsonDocument<500> doc;
JsonArray analogValues = doc.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(35);
analogValues.add(value);
}
Serial.print(F("Reading: "));
serializeJson(doc, Serial);
Serial.println();
}

Your code will take 7 samples from the input pin very quickly - faster than it's likely you'll be able to change the potentiometer. You need to add a delay between the samples to give the potentiometer time to change. So:
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(35);
analogValues.add(value);
delay(200);
}
would wait 2 tenths of a second between taking samples.
To do some very basic debugging on this you could also confirm that the issues is the samples themselves and not the way you're handling JSON by outputting the sample values as you take them. In your original code this would be:
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(35);
Serial.println(value);
analogValues.add(value);
}
It's also possible that the act of outputting the samples might slow things down enough that you might start to see variation.

Related

Converting Big endian values that i receive on Modbus to float value

I am writing some code for Modbus RTU but having a problem converting data received.
below is the code and i am able to communicate with Slave device, however the info i receive back does not make sense at all.
The slave address is 2000 ( hex value) and Datablocks are 2 and Hex response is Float - Big Endian (ABCD) .
However when i view via serial print it makes no sense. Anyone that can help would be greatly appreciated.
void loop()
{
uint8_t j, result;
uint16_t data[6];
// slave: read (6) 16-bit registers starting at register .. to RX buffer , this address is in Decimal, so convert hex to decimal to use correct address
result = node.readHoldingRegisters(8192, 2);
// do something with data if read is successful
if (result == node.ku8MBSuccess)
{
for (j = 0; j < 6; j++)
{
data[j] = node.getResponseBuffer(j);
Serial.println(data[j]);
}
}
delay(1000);
}

C - pass array as parameter and change size and content

UPDATE: I solved my problem (scroll down).
I'm writing a small C program and I want to do the following:
The program is connected to a mysql database (that works perfectly) and I want to do something with the data from the database. I get about 20-25 rows per query and I created my own struct, which should contain the information from each row of the query.
So my struct looks like this:
typedef struct {
int timestamp;
double rate;
char* market;
char* currency;
} Rate;
I want to pass an empty array to a function, the function should calculate the size for the array based on the returned number of rows of the query. E.g. there are 20 rows which are returned from a single SQL query, so the array should contain 20 objectes of my Rate struct.
I want something like this:
int main(int argc, char **argv)
{
Rate *rates = ?; // don't know how to initialize it
(void) do_something_with_rates(&rates);
// the size here should be ~20
printf("size of rates: %d", sizeof(rates)/sizeof(Rate));
}
How does the function do_something_with_rates(Rate **rates) have to look like?
EDIT: I did it as Alex said, I made my function return the size of the array as size_t and passed my array to the function as Rate **rates.
In the function you can access and change the values like (*rates)[i].timestamp = 123 for example.
In C, memory is either dynamically or statically allocated.
Something like int fifty_numbers[50] is statically allocated. The size is 50 integers no matter what, so the compiler knows how big the array is in bytes. sizeof(fifty_numbers) will give you 200 bytes here.
Dynamic allocation: int *bunch_of_numbers = malloc(sizeof(int) * varying_size). As you can see, varying_size is not constant, so the compiler can't figure out how big the array is without executing the program. sizeof(bunch_of_numbers) gives you 4 bytes on a 32 bit system, or 8 bytes on a 64 bit system. The only one that know how big the array is would be the programmer. In your case, it's whoever wrote do_something_with_rates(), but you're discarding that information by either not returning it, or taking a size parameter.
It's not clear how do_something_with_rates() was declared exactly, but something like: void do_something_with_rates(Rate **rates) won't work as the function has no idea how big rates is. I recommend something like: void do_something_with_rates(size_t array_size, Rate **rates). At any rate, going by your requirements, it's still a ways away from working. Possible solutions are below:
You need to either return the new array's size:
size_t do_something_with_rates(size_t old_array_size, Rate **rates) {
Rate **new_rates;
*new_rates = malloc(sizeof(Rate) * n); // allocate n Rate objects
// carry out your operation on new_rates
// modifying rates
free(*rates); // releasing the memory taken up by the old array
*rates = *new_rates // make it point to the new array
return n; // returning the new size so that the caller knows
}
int main() {
Rate *rates = malloc(sizeof(Rate) * 20);
size_t new_size = do_something_with_rates(20, &rates);
// now new_size holds the size of the new array, which may or may not be 20
return 0;
}
Or pass in a size parameter for the function to set:
void do_something_with_rates(size_t old_array_size, size_t *new_array_size, Rate **rates) {
Rate **new_rates;
*new_rates = malloc(sizeof(Rate) * n); // allocate n Rate objects
*new_array_size = n; // setting the new size so that the caller knows
// carry out your operation on new_rates
// modifying rates
free(*rates); // releasing the memory taken up by the old array
*rates = *new_rates // make it point to the new array
}
int main() {
Rate *rates = malloc(sizeof(Rate) * 20);
size_t new_size;
do_something_with_rates(20, &new_size, &rates);
// now new_size holds the size of the new array, which may or may not be 20
return 0;
}
Why do I need to pass the old size as a parameter?
void do_something_with_rates(Rate **rates) {
// You don't know what n is. How would you
// know how many rate objects the caller wants
// you to process for any given call to this?
for (size_t i = 0; i < n; ++i)
// carry out your operation on new_rates
}
Everything changes when you have a size parameter:
void do_something_with_rates(size_t size, Rate **rates) {
for (size_t i = 0; i < size; ++i) // Now you know when to stop
// carry out your operation on new_rates
}
This is a very fundamental flaw with your program.
I want to also want the function to change the contents of the array:
size_t do_something_with_rates(size_t old_array_size, Rate **rates) {
Rate **new_rates;
*new_rates = malloc(sizeof(Rate) * n); // allocate n Rate objects
// carry out some operation on new_rates
Rate *array = *new_rates;
for (size_t i = 0; i < n; ++i) {
array[i]->timestamp = time();
// you can see the pattern
}
return n; // returning the new size so that the caller knows
}
sizeof produces a value (or code to produce a value) of the size of a type or the type of an expression at compile time. The size of an expression can therefore not change during the execution of the program. If you want that feature, use a variable, terminal value or a different programming language. Your choice. Whatever. C's better than Java.
char foo[42];
foo has either static storage duration (which is only partially related to the static keyword) or automatic storage duration.
Objects with static storage duration exist from the start of the program to the termination. Those global variables are technically called variables declared at file scope that have static storage duration and internal linkage.
Objects with automatic storage duration exist from the beginning of their initialisation to the return of the function. These are usually on the stack, though they could just as easily be on the graph. They're variables declared at block scope that have automatic storage duration and internal linkage.
In either case, todays compilers will encode 42 into the machine code. I suppose it'd be possible to modify the machine code, though that several thousands of lines you put into that task would be much better invested into storing the size externally (see other answer/s), and this isn't really a C question. If you really want to look into this, the only examples I can think of that change their own machine code are viruses... How are you going to avoid that antivirus heuristic?
Another option is to encode size information into a struct, use a flexible array member and then you can carry both the array and the size around as one allocation. Sorry, this is as close as you'll get to what you want. e.g.
struct T_vector {
size_t size;
T value[];
};
struct T_vector *T_make(struct T_vector **v) {
size_t index = *v ? (*v)->size++ : 0, size = index + 1;
if ((index & size) == 0) {
void *temp = realloc(*v, size * sizeof *(*v)->value);
if (!temp) {
return NULL;
}
*v = temp;
// (*v)->size = size;
*v = 42; // keep reading for a free cookie
}
return (*v)->value + index;
}
#define T_size(v) ((v) == NULL ? 0 : (v)->size)
int main(void) {
struct T_vector *v = NULL; T_size(v) == 0;
{ T *x = T_make(&v); x->value[0]; T_size(v) == 1;
x->y = y->x; }
{ T *y = T_make(&v); x->value[1]; T_size(v) == 2;
y->x = x->y; }
free(v);
}
Disclaimer: I only wrote this as an example; I don't intend to test or maintain it unless the intent of the example suffers drastically. If you want something I've thoroughly tested, use my push_back.
This may seem innocent, yet even with that disclaimer and this upcoming warning I'll likely see a comment along the lines of: Each successive call to make_T may render previously returned pointers invalid... True, and I can't think of much more I could do about that. I would advise calling make_T, modifying the value pointed at by the return value and discarding that pointer, as I've done above (rather explicitly).
Some compilers might even allow you to #define sizeof(x) T_size(x)... I'm joking; don't do this. Do it, mate; it's awesome!
Technically we aren't changing the size of an array here; we're allocating ahead of time and where necessary, reallocating and copying to a larger array. It might seem appealing to abstract allocation away this way in C at times... enjoy :)

CUDA: Copy 1D array from GPU to 2D array on host

int main() {
char** hMat,* dArr;
hMat = new char*[10];
for (int i=0;i<10;i++) {
hMat[i] = new char[10];
}
cudaMalloc((void**)&dArr,100);
// Copy from dArr to hMat here:
}
I have an array, dArr on the GPU, and I want to copy it into a 2D array hMat on the host, where the first 10 fields in the GPU array are copied to the first row in the host matrix, and the next 10 fields are copied to the second row, and so on.
There are some functions in the documentation, namely CudaMemcpy2D and CudaMemcpy2DFromArray, but I'm not quite sure how they should be used.
Your allocation scheme (an array of pointers, separately allocated) has the potential to create a discontiguous allocation on the host. There are no cudaMemcpy operations of any type (including the ones you mention) that can target an arbitrarily discontiguous area, which your allocation scheme has the potential to create.
In a nutshell, then, your approach is troublesome. It can be made to work, but will require a loop to perform the copying -- essentially one cudaMemcpy operation per "row" of your "2D array". If you choose to do that, presumably you don't need help. It's quite straightforward.
What I will suggest is that you instead modify your host allocation to create an underlying contiguous allocation. Such a region can be handled by a single, ordinary cudaMemcpy call, but you can still treat it as a "2D array" in host code.
The basic idea is to create a single allocation of the correct overall size, then to create a set of pointers to specific places within the single allocation, where each "row" should start. You then reference into this pointer array using your initial double-pointer.
Something like this:
#include <stdio.h>
typedef char mytype;
int main(){
const int rows = 10;
const int cols = 10;
mytype **hMat = new mytype*[rows];
hMat[0] = new mytype[rows*cols];
for (int i = 1; i < rows; i++) hMat[i] = hMat[i-1]+cols;
//initialize "2D array"
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
hMat[i][j] = 0;
mytype *dArr;
cudaMalloc(&dArr, rows*cols*sizeof(mytype));
//copy to device
cudaMemcpy(dArr, hMat[0], rows*cols*sizeof(mytype), cudaMemcpyHostToDevice);
//kernel call
//copy from device
cudaMemcpy(hMat[0], dArr, rows*cols*sizeof(mytype), cudaMemcpyDeviceToHost);
return 0;
}

Allocating using malloc inside a function passing the address of the pointer and using vector syntax?

What's wrong on the code below? I need to send the address of the pointer *A to the function, read some numbers with scanf inside it, return to main and print the numbers read at that function.
void create_number_vector(int **number)
{
(*number) = (int*)malloc(5*sizeof(int));
int i;
for(i=0; i<5; i++){
scanf("%d",number[i]);
}
}
int main(void){
int i, *A;
create_number_vector(&A);
for(i=0; i<5; i++){
printf("%d",A[i]);
}
return 0;
}
Except one line(concept), everything is pretty much OK.
Problamatic line is:
scanf("%d",number[i]);
And should be replace with:
scanf("%d", *number+i);
Because our allocated variable is a pointer, we should use him like that, we should go to the 'i' address inside of the allocated variable and scan into him.
Ofcourse you can keep on using the "array" style usage, with this syntax:
scanf("%d", &(*number)[i]);
P.S
Don't forget to free the allocated resources at the end of the usage, altough this kind of small program that exits at the end of the echoing, it's still a good practice to always free your resources at the end of its usage.

Problem with constructor - initialization list (c++)

it's a weird problem that I have
I have a very simple constructor that's creates a matrix with no values:
RegMatrix::RegMatrix(const int numRow, const int numCol):
_numRow(numRow),_numCol(numCol),_matrix()
{
}
_matrix is a vector that holds 'Comlex', an object I've created
and VAL(i,j) is #define VAL(i,j) ((i * _numCol) + j)
Now, I call this constructor in function transpose:
RegMatrix RegMatrix::transpose()
{
RegMatrix newMatrix(_numCol,_numRow);
cout << "DIMENSIONS " << newMatrix._numRow << " " << newMatrix._numCol << endl;
for(int j=0; j<_numCol; j++)
{
for(int i=0; i<_numRow; i++)
{
newMatrix._matrix[VAL(i,j)] = _matrix[VAL(j,i)]; //<--SEGMENTATION FAULT
}
}
return newMatrix;
}
And here's my problem: I get a segmentation fault the very first time I enter the second loop. When I use the eclipse debugger I see that _nunRow and _numCol values of newMatrix seem to be garbage (one is '0' the other is -10000000 or something like that). What's even more weird is that I added the output line just to be sure and it gave me the right numbers!
So, any ideas as to what can be my problem?
Thanks!
You are indexing into an empty vector, which is doomed to fail. Use at instead of the subscript operator and you will get an exception.
My guess (based on what you show) is that there may be some problems with how you implement the copy constructor.