I want to get string using RX_interrupt in MBED - c

I’m trying to write code using MBED, but there are some problems.
The thing is that I want to get "character array".
If I send "abcde" to the MBED board, the board will get "abcde" and do something.
This is my code.
#include <mbed.h>
char message[200];
void Rx_interrupt();
int i;
Serial pc(PA_2, PA_3);
int main() {
pc.baud(115200);
pc.attach(&Rx_interrupt, Serial::RxIrq);
while (1) {
}
return 0;
}
void Rx_interrupt() {
char a1[6] = "abcde";
memset(message, 0, sizeof(message));
i = 0;
while (pc.readable()) {
message[i] = pc.getc();
i++;
}
if (!strcmp(a1, message)) {
pc.printf(message);
}
else {
pc.printf("FAIL");
}
}
If I send "abcde", the board should print "abcde". This is my purpose.
But the board prints "FAIL" only one time. What should I do?
I think that there are some problems with pc.getc().

Related

ESP8266- Buffer storage capacity from the UART

I have an issue while transferring the values of string from UART to buffer. I am using ESP8266 to receive strings on serial from STM32 device. I have total 600 string and i have CSV file that is being transmitted from the STM32 device. I have used proper filtering for every row on the NodeMCU side... I am having no clue why after 300 string the value transmitted to the buffer gets changed as well as the string read on UART also changes exactly after 300/305 string being transmitted. please let me know if there's any mistake in the code.
int i,j,k,l=0;
int httpCode=0;
String fields[24] = {"","month","year","hours","minutes","seconds","rimin","riavg","rimax","yimin","yiavg","yimax","bimin","biavg","bimax","nimin","niavg","nimax","eimin","eiavg","eimax","simin","siavg","simax"};
String element = "API_key=123&mac=0fa&day=";
String postApi1[300];
String postApi2[300];
String str= "";
String str_tx = "";
char char_array[128];
char* token;
char* rest = char_array;
WiFiClient client;
HTTPClient http;
void setup()
{
Serial.begin(230400);
s.begin(9600);
pinMode(13, INPUT);
pinMode(15, OUTPUT);
}
void loop()
{
if (s.available() >0)
{
for(j=0;j<300;j++)
{
i=0;
str = s.readStringUntil('\n');
Serial.println(str);
Serial.println("j");
postApi1[j]= str;
Serial.println(postApi1[j]);
str = "";
}
for(k=0;k<300;k++)
{
i=0;
str = s.readStringUntil('\n');
Serial.println(str);
Serial.println("k");
postApi2[k]= str;
Serial.println(postApi2[k]);
str = "";
}
}
}
Here is the code i am using and following is the Serial output of the code.
I think that the readStringUntil function waits for the terminator char. Is the '\n' sent also after 300th character? Also, try to avoid Serial.println in the read function, since the print function is quite slow, you might miss some characters. I would also avoid two for loops, instead, declare a variable, count number of received bytes and according to this save the "str" into "postApi1" or "postApi2".
Also, what is the purpose of "i" variable?
Hey #Andrej I tried your suggestion but it worked as follows
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <SoftwareSerial.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <stdio.h>
#include <string.h>
using namespace std;
ESP8266WiFiMulti WiFiMulti;
SoftwareSerial s(13,15); //RX TX
double buff[24]; //Initialized variable to store recieved data
double val;
char c;
int i,j,k,l=0;
int httpCode=0;
String fields[24] = {"","month","year","hours","minutes","seconds","rimin","riavg","rimax","yimin","yiavg","yimax","bimin","biavg","bimax","nimin","niavg","nimax","eimin","eiavg","eimax","simin","siavg","simax"};
String element = "API_key=123&mac=0fa&day=";
String postApi[616];
String str= "";
String str_tx = "";
char char_array[128];
char* token;
char* rest = char_array;
WiFiClient client;
HTTPClient http;
void setup()
{
Serial.begin(230400);
s.begin(9600);
pinMode(13, INPUT);
pinMode(15, OUTPUT);
//Serial.setDebugOutput(true);
//ESP.wdtDisable();
//Serial.begin(115200);
// Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("ECLP", "p##$w0rD");
if ((WiFiMulti.run() == WL_CONNECTED))
{
Serial.print("WIFI connected");
}
}
void loop()
{
if (s.available() >0)
{
for(j=0;j<616;j++)
{
i++;
str = s.readStringUntil('\n');
//Serial.println(str);
//Serial.println(j);
postApi[j]= str;
//Serial.println(postApi[j]);
str = "";
}
}
if(i == 616)
{
i=0;
for(k=0;k<616;k++)
{
Serial.println(k);
Serial.print(" : ");
Serial.print(postApi[k]);
}
}
}
And receive on the output the following thing
Just for the ref i printed "k" value with output to know at which string the data loss occurs in buffer

how to remove certain words from a line of text in c

I got my code working to an extent, but I need some more help. If I needed to remove the word "an", from sentence: "I ate an apple whilst looking at an ape.", it only removes the first "an" and not the second, how do I repeat the loop so it deletes all "an"s? I need the final sentence, after the code has been ran, to be: "I ate apple whilst looking at ape.". That is the goal im trying to achieve
Sorry for not including the code.
Here it is:
#include "RemoveFromText.h"
#include <stdlib.h>
#include <string.h>
int findFirstSubstring(char textToChange[], char removeThis[])
{
int size = strlen(textToChange);
int subStringLength = strlen(removeThis);
for(int i=0; i<size; i++)
{
if(textToChange[i] == removeThis[0])
{
int j = 0;
while(textToChange[i+j] == removeThis[j])
{
j++;
if(j==subStringLength)
{
return i;
}
}
}
}
return -1;
}
void removeFromText( char textToChange[], char removeThis[])
{
int textLength = strlen(textToChange);
if(findFirstSubstring(textToChange, removeThis) >= 0)
{
int subStringIdx = findFirstSubstring(textToChange, removeThis);
int loopVariabele = 0;
for(loopVariabele = subStringIdx; loopVariabele<textLength; loopVariabele++)
{
textToChange[loopVariabele] = textToChange[loopVariabele + strlen(removeThis)];
}
}
}
Leveraging 'strstr', and 'memmove' standard "C" library functions
// Remove all occurences of 'source' from 'message'.
void removeAll(char *message, char *source)
{
int len = strlen(source) ;
for (char *x = message ; x=strstr(x, source) ; ) {
// Copy everything after 'source', including terminating nul.
memmove(x, x+len, strlen(x+len)+1) ;
} ;
}
Notes:
that solution that not properly address the trailing space(s) after a word. This can be addressed by chaning the 'memmove'.
Probably make sense to make the function return the number of substitutions, or some other meaningful result

Python's binascii.unhexlify function in C

I'm building a program that takes input as if it is a bare MAC address and turn it into a binary string. I'm doing this on a embedded system so there is no STD. I have been trying something similar to this question but after 2 days I haven't achieved anything, I'm really bad with these kind of things.
What I wanted is output to be equal to goal, take this into consideration:
#include <stdio.h>
int main() {
const char* goal = "\xaa\xbb\xcc\xdd\xee\xff";
printf("Goal: %s\n", goal);
char* input = "aabbccddeeff";
printf("Input: %s\n", input);
char* output = NULL;
// Magic code here
if (output == goal) {
printf("Did work! Yay!");
} else {
printf("Did not work, keep trying");
}
}
Thanks, this is for a personal project and I really want to finish it
First, your comparison should use strcmp else it'll be always wrong.
Then, I would read the string 2-char by 2-char and convert each "digit" to its value (0-15), then compose the result with shifting
#include <stdio.h>
#include <string.h>
// helper function to convert a char 0-9 or a-f to its decimal value (0-16)
// if something else is passed returns 0...
int a2v(char c)
{
if ((c>='0')&&(c<='9'))
{
return c-'0';
}
if ((c>='a')&&(c<='f'))
{
return c-'a'+10;
}
else return 0;
}
int main() {
const char* goal = "\xaa\xbb\xcc\xdd\xee\xff";
printf("Goal: %s\n", goal);
const char* input = "aabbccddeeff";
int i;
char output[strlen(input)/2 + 1];
char *ptr = output;
for (i=0;i<strlen(input);i+=2)
{
*ptr++ = (a2v(input[i])<<4) + a2v(input[i]);
}
*ptr = '\0';
printf("Goal: %s\n", output);
if (strcmp(output,goal)==0) {
printf("Did work! Yay!");
} else {
printf("Did not work, keep trying");
}
}

Very Basic Encryption

#include <stdio.h>
int limit;
char alp[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
void encode(char message[21],char enc_message[21],int key);
void decode(char enc_message[21],char dec_message[21],int key);
main()
{
int key,i=0,j=0;
char message[21];
char enc_message[21];
char dec_message[21];
char encrypted[21];
char a='\0';
printf("Input the characters to encrypt\n");
while(i<21 && a!='\n')
{
scanf("%c",&a);
message[i]=a;
i=i+1;
}
for(i=0;;i++) /*custom strlen*/
{
if( message[i]= '\0')
{
limit=i;
break;
}
}
printf("Input the key");
scanf("%d",key);
for(i=0;i<21;i++)
{
enc_message[i]=message[i];
}
encode(message[21],enc_message[21],key);
for(i=0;i<21;i++)
{
dec_message[i]=enc_message[i];
}
for(i=0;i<limit;i++)
{
printf("%c",enc_message[i]);
}
printf("\n\n");
decode(enc_message[21],dec_message[21],key);
for(i=0;i<limit;i++)
{
printf("%c",dec_message[i]);
}
}
void encode(char message[21],char enc_message[21],int key)
{
/*char temp[21];*/
int x,y;
for(x=0;x<limit;x++) /* message check */
{
for(y=0;y<26;y++) /* <----- alphabet check */
{
if (enc_message[x]==alp[y]) enc_message[x]=alp[y+key];
}
}
}
/*------------------------------------------------------------------------*/
void decode(char enc_message[21],char dec_message[21],int key)
{
int x,y;
for (x=0;x<limit;x++)
{
for(y=0;y<26;y++)
{
if (dec_message[x]==alp[y+key]) dec_message[x]=alp[y];
}
}
}
The compiler says,the mistake has to do with the way I call functions(and write them)and says: passing argument1 of 'encode' makes pointer from integer without a cast ,and that is for argument 2 of 'encode' and the exact same for 'decode'
Thanks in advance!
You are passing a single element and it's not even a valid element, try
decode(enc_message, dec_message, key);
Also, format your code so it's readable that is really important, and looping to compute the length of the string to use it in another loop is not a very smart thing, print it in a loop like
for (int i = 0 ; enc_message[i] != '\0' ; ++i) ...
also, don't over use break, just think about the logical condition for the loop, it's the same one where you break. Code is much more readable if the condition appears in the right place.

User entered string run a particular function in c

Guys so I'm working on the web service assignment and I have the server dishing out random stuff and reading the uri but now i want to have the server run a different function depending on what it reads in the uri. I understand that we can do this with function pointers but i'm not exactly sure how to read char* and assign it to a function pointer and have it invoke that function.
Example of what I'm trying to do: http://pastebin.com/FadCVH0h
I could use a switch statement i believe but wondering if there's a better way.
For such a thing, you will need a table that maps char * strings to function pointers. The program segfaults when you assign a function pointer to string because technically, a function pointer is not a string.
Note: the following program is for demonstration purpose only. No bounds checking is involved, and it contains hard-coded values and magic numbers
Now:
void print1()
{
printf("here");
}
void print2()
{
printf("Hello world");
}
struct Table {
char ptr[100];
void (*funcptr)(void)
}table[100] = {
{"here", print1},
{"hw", helloWorld}
};
int main(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < 2; i++){
if(!strcmp(argv[1],table[i].ptr) { table[i].funcptr(); return 0;}
}
return 0;
}
I'm gonna give you a quite simple example, that I think, is useful to understand how good can be functions pointers in C. (If for example you would like to make a shell)
For example if you had a struct like this:
typedef struct s_function_pointer
{
char* cmp_string;
int (*function)(char* line);
} t_function_pointer;
Then, you could set up a t_function_pointer array which you'll browse:
int ls_function(char* line)
{
// do whatever you want with your ls function to parse line
return 0;
}
int echo_function(char* line)
{
// do whatever you want with your echo function to parse line
return 0;
}
void treat_input(t_function_pointer* functions, char* line)
{
int counter;
int builtin_size;
builtin_size = 0;
counter = 0;
while (functions[counter].cmp_string != NULL)
{
builtin_size = strlen(functions[counter].cmp_string);
if (strncmp(functions[counter].cmp_string, line, builtin_size) == 0)
{
if (functions[counter].function(line + builtin_size) < 0)
printf("An error has occured\n");
}
counter = counter + 1;
}
}
int main(void)
{
t_function_pointer functions[] = {{"ls", &ls_function},
{"echo", &echo_function},
{NULL, NULL}};
// Of course i'm not gonna do the input treatment part, but just guess it was here, and you'd call treat_input with each line you receive.
treat_input(functions, "ls -laR");
treat_input(functions, "echo helloworld");
return 0;
}
Hope this helps !

Resources