sending data from microcontroller to the computer using tiva series c - c

I am using Tiva C Series TM4C123GH6PM with Code Composer Studio for getting data from another microcontroller of the same type. Well, I get the data in bytes. The Goal of project is to assemble each 8 bytes and convert them to double then send these double to the computer. I have to use USART to send the data to the computer.
When I use USART, I have two Methods:
One to get data from a USART_x: UARTCharGet(UART1_BASE)
The other to send the data over USART_x: UARTCharPut(UART0_BASE,d)
The problem consists in having two methods that accept only characters. So using these methods for double is impossible since a double is 8 bytes and a character is one byte. I am trying to send doubles to my computer. Any idea?
The second Problem is to write a program from the side of the computer to get the data (bytes) from the microcontroller.
Should I write this program in c (an alternative is using matlab because I will use these data for simulation)?
How can I access com-Port in c (or in matlab if it is possible)?

You need to find a way to break up large amounts of data, and send it to the client, who then needs a way to re-assemble the data, and also know when such data is being sent.
A very simple approach would be to convert all the digits of the double to characters. Inefficient, but it gets the job done easily enough, as shown below. The reason this is preferable is because it lets you easily create your own "instruction set". For example, you could reserve the character '!' as "the letter following ! denotes a special instruction", so when the client sees the sequence "!d", it knows the following 32 bytes of data represent a double, and to re-assemble it.
If you just send the raw bytes, it becomes more convoluted when you want to create escape codes or op codes to signal special circumstances to the client.
Code Listing
#include <stdio.h>
#define BUF_LEN (32)
typedef union {
float f;
struct {
unsigned int mantissa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
} parts;
} double_cast;
int main(void)
{
double_cast d1;
d1.f = 0.15625;
printf("sign = %x\n",d1.parts.sign);
printf("exponent = %x\n",d1.parts.exponent);
printf("mantissa = %x\n",d1.parts.mantissa);
char buf[BUF_LEN+1] = { 0 };
snprintf(buf, BUF_LEN+1, "%01X%08X%023X", d1.parts.sign, d1.parts.exponent,
d1.parts.mantissa);
// Send over UART
printf("Double as string: [%s]\n", buf);
//UART_printf("!d%s", buf);
return 0;
}
Sample Output
sign = 0
exponent = 7c
mantissa = 200000
Double as string: [00000007C0000000000000000020000]
Credit for the code to break a double into a string goes to u/eran.

Another solution (similar to the solution of Krystian) that works for me. I defined a function that has as parameters a double and an array of Bytes. The double must be converted to an array of Bytes. That´s why I defined an array of Bytes which has a size of 8 Bytes. Here some code:
unsigned char bytesArray[sizeof(double)];
unsigned char * doubleToBytes(double num,unsigned char bytes []){
return memcpy(bytes,&num,sizeof(double));
}
After getting the Bytes in the Array you can send data using the following loop:
for(i=0;i<sizeof(double);i++){
UARTCharPut(UART1_BASE,(unsigned char)*(bytesArray+i));
}

Generally speaking you are facing here serialization problem and the best approach would be using specialized library for this purpose.
In a dirty but simple way you can solve it like that. You have to just properly assemble your data on the other side back to double.
typedef union _MyDouble {
double d;
unsigned char bytes[sizeof(double)];
} MyDouble;
MyDouble my_double;
my_double.d = 1.234;
for(i=0; i < sizeof(double); i++) {
UARTCharPut(UART0_BASE, (char)my_double.bytes[i]).
}
The other thing is that if you are using UART you should encapsulate this union into some frame e.g. in order to successfully reassemble this on the other side.
_____________ ________ __________ ___________ ________
| | | | | |
| FRAME_BEGIN | LENGTH | MyDouble | FRAME_END | CRC-8? |
|_____________|________|__________|___________|________|
The next thing is that you should probably enforce byte alignment on this struct which is done by the compiler directives. It ensures that your struct has no padding bytes etc. and allocates minimum requires size. This is very popular in embedded applications use-cases where some binary object is going to be transmitted on the serial interface - which is exactly your case. Such a simple solution might work on specific hw+sw configuration but for sure it is not portable and good solution from professional point of view.

Related

Print a big integer stored as an unsigned long long array

I'm reviewing the security of an app for a University project, the app encrypts a file using RSA, specifically it uses this library: https://github.com/ilansmith/rsa (DO NOT use this, it has serious vulnerabilities).
(If you want to take a look, most of the operations between these numbers are implemented in the rsa_num.c file.)
This tool uses arrays of unsigned long long to store the big numbers needed for RSA (n, e and d):
typedef struct {
u64 arr[17]; //u64 is defined as unsigned long long
int top; //points to the last occupied slot of the array
} u1024_t;
The problem is that I don't understand how the numbers are stored in this format.
What I need is being able to print the real numbers in some way, or at least a way to recover the numbers from the components of the arrays.
I tried just concatenating them like strings, but it doesn't seem right.
Thanks to whoever will be able to help!
Thank you #Matthieu! Your comment worked.
I needed to concatenate the unsigned long longs in reverse order and reversing their bytes due to endianness.
Following his solution, I implemented this function, which works perfectly:
void print_u1024(u1024_t number) {
int size = (number.top + 1) * sizeof(u64);
for (int i = size-1; i >= 0; i--) {
printf("%02x", ((unsigned char*)number.arr)[i]);
}
printf("\n");
}
Please note that this solution will probably only work on little-endian systems (most PCs).

Embedded C AVR Bit stuffing an array

Can anyone help me with some code i need to implement bit stuffing on an array of data? The program is for an AVR micro-controller (Tiny84A) using GNU C.
unsigned char datas[3] = {00011111,10000001,00000000};
To add 0 to each set of 5 one’s i.e. after every five consecutive 1′s appear a zero
Therefore data should be
00011111,10000001 becomes 00011111 01000000 10000000
I'm unsure where to start, an example would be great!
There are lots of examples on the web for bit stuffing (inserting a 0 after 5 1s). Unfortunately, many of them involve reading and writing strings of characters 0 and 1.
There are also examples of bit streams. It looks like you need to find examples of each and combine them.
You need to expand your question to explain more of the design decisions you have made.
In particular, it looks like you are expecting the input to be in an array instead of a stream. Are you expecting to write the output to the same array? That is a little bit trickier than writing to a different array. A stream of bits would be different again.
The basic idea is to keep counters of where you are in the input and output streams, and load and write bytes appropriately as you reach the end of 8 bits.
unsigned char datas[3] = {00011111,10000001,00000000};
int in_byte, in_bit, out_byte, out_bit;
void init()
{
in_byte = 0; in_bit = 0; out_byte = 0; out_bit = 0;
}
int get_bit()
{
int ret = 0;
if (datas[in_byte] & 1 << (7 - in_bit))
{
ret = 1;
{
++in_bit;
if (in_bit == 8)
{
in_bit = 0;
++in_byte;
}
return ret;
}
You have to write your own void put_bit(int bit), but it is similar using the "or" operator |.
You also need to make a function to do the loop that counts up to 5 and puts an extra 0. Look at the examples on the web for that.

converting data types in c

Let me start by saying that I openly admit this is for a homework assignment, but what I am asking is not related to the purpose of the assignment, just something I don't understand in C. This is just a very small part of a large program.
So my issue is, I have a set of data that consists various data types as follows:
[16 bit number][16 but number][16 bit number][char[234]][128 bit number]
where each block represents a variable from elsewhere in the program.
I need to send that data 8bytes at a time into a function that accepts uint32_t[2] as an input. How do I convert my 234byte char array into uint32_t without losing the char values?
In other words, I need to be able to convert back from the uint32_t version to the original char array later on. I know a char is 1byte, and the value can also be represented as a number in relation to its ascii value, but not sure how to convert between the two since some letters have a 3 digit ascii value and others have 2.
I tried to use sprintf to grab 8byte blocks from the data set, and store that value in a uint32_t[2] variable. It works, but then I lose the original char array because I can't figure out way to go back/undo it.
I know there has to be a relatively simple way to do this, i'm just lacking enough skill in C to make it happen.
Your question is very confusing, but I am guessing you are preparing some data structure for encryption by a function that requires 8 bytes or 2 uint32_t's.
You can convert a char array to uint32_t as follows
#define NELEM 234
char a[NELEM];
uint64_t b[(NELEM+sizeof(uint64_t)-1)/sizeof(uint64_t)]; // this rounds up to nearest modulo 4
memcpy(b,a,NELEM);
for(i .. ) {
encryption_thing(b[i]);
}
or
If you need to change endianess or something, that is more complicated.
#include <stdint.h>
void f(uint32_t a[2]) {}
int main() {
char data[234]; /* GCC can explicitly align with this: __attribute__ ((aligned (8))) */
int i = 0;
int stride = 8;
for (; i < 234 - stride; i += stride) {
f((uint32_t*)&data[i]); }
return 0; }
I need to send that data 8bytes at a time into a function that accepts
uint32_t[2] as an input. How do I convert my 234byte char array into
uint32_t without losing the char values?
you could use a union for this
typedef union
{
unsigned char arr[128]; // use unsigned char
uint32_t uints[16]; // 128/8
} myvaluetype;
myvaluetype value;
memcpy(value.arr, your_array, sizeof(value.arr));
say the prototype that you want to feed 2 uint32_t at a time is something like
foo(uint32_t* p);
you can now send the data 8 bytes at the time by
for (int i = 0; i < 16; i += 2)
{
foo(myvaluetype.uints + i);
}
then use the same struct to convert back.
of course some care must be taken about padding/alignment you also don't mention if it is sent over a network etc so there are other factors to consider.

How to put digits of a long long int into a long long int array

ok so I am trying to implement Client - server program (socket programming).
My client send a long long int embedded in a string like this:
char copy[10];
sprintf(send_data,"%s","Pre=");
for(i=0;i<7;i++){
sprintf(copy,"%lld",premaster[i]);
strcat(send_data,copy);
}
printf("\nSending CLIENT_KEY_EXCHANGE message\n");
send(sock,send_data,strlen(send_data), 0);
SO send_data looks like Pre=278262617263
Now on the server side thus is what it looks like:
long long int preMaster;
long long int pre[100]={0};
numBytes = recv(clntSock,inMsg,1024,0);
inMsg[numBytes] = '\0';
sscanf(inMsg, "Pre=%lld", &preMaster);
now I want to convert this preMaster into the element of pre array. How do I go about doing that?
You cannot do this, because you are sending ambiguous information: Pre=278262617263 could mean any of the following:
An array of one number 278262617263
An array of two numbers 27826261726 and 3
An array of two numbers 2782626172 and 63
An array of two numbers 278262617 and 263
... more of the same
An array of three numbers 2782626172, 6 and 3
... I think you got the idea
Fixing this requires fixing the sender first: make sure that you separate your numbers with a delimiter, and optionally send the number of items in the array to avoid dynamic re-allocation - for example,
Pre=5:27,826,26,17,263
is no longer ambiguous: it says that you are sending 5 items, and these items are delimited.

Reading pixel data of a PPM file using C

I am trying to read pixel data from a PPM file. I have a function to read the header so I know it's pointing to the beginning of the pixel data. I tried using fgetc(file) but if the value is more than one digit it will not work. I also tried using an array and converting the array to an int or char but I have no way of knowing how many digits each value is. I'm also not sure if the values are separated by whitespace or not. Basically I need a way to extract the pixel data. (I'm using C.)
My code right now is:
char read_byte(FILE *ipt) {
int c, i=0, sum=0;
while (i<16) {
c=fgetc(ipt);
if((i%2)!=0 {
if(c&1) {
sum+=pow(2,i/2);
}
}
i++;
}
return (char)sum;
}
EDIT:
At first I thought the file was stored as the ASCII values, then I realized it's stored as binary. Right now I think I'm making it act like hex. I'm not sure if that's correct. I'm really stuck.
EDIT: changed my code a bit
char read_byte(FILE *ipt) {
int c, i=0, sum=0;
while(i<8) {
c = fgetc(ipt);
c=c&1;
sum+=c*pow(2,i);
i++;
}
return sum;
}
I print the sum as %c
Must you write this for an assignment, or is it for pleasure, or could you use someone else's code?
There is an Open Source solution.
"Netpbm is a package of graphics programs and a programming library. " which includes programs to read PPM at http://netpbm.sourceforge.net/doc/
Edit:
Have you got, or read the definition of the file format, e.g. http://netpbm.sourceforge.net/doc/ppm.html?
It looks like the data is either sequences of one byte RGB triples, or sequences of two byte RGB triples.
The program can detect which format is used from item 7 "The maximum color value (Maxval)". It says "If the Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes."
So you code a function which reads one byte/component RGB data, then code another to read two byte/component RGB data.
The program can choose which to call once it has read the value of Maxval.
Edit {
According to the document at that link, the image data in a 'P6' ppm is binary.
So if MaxValue is <256, and hence the data for each colour component is one byte, then reading three bytes, with three calls of fgetc(fp) would return the binary value of one RGB pixel.
If the program has read the header, it has the values of width and height for the image data. So it could allocate an array for every row (width wide of RGB pixels), and an array of pointers to each allocated pixel row array. Then read the binary data into each row, and the program has something straightforward to operate on; a 2d array.
} end edit
My reading of your question suggests you already know how to read one byte data using fgetc.
Edit - it seems like this is irrelevant:
You can read two byte data by calling fgetc twice, and shifting and bit or-ing the data, e.g. (partly ignoring error checking):
int a = fgetc(fp);
int b = fgetc(fp);
if (a >= 0 && b >= 0) { // then all is okay
unsigned int twobyte = (a<<8) | b; // or (b<<8) | a; depending on byte order
// ...

Resources