How to write numbers in text files in embedded C - c

I'm working with an EFM32wg280f256 and I would like to debug the code that I'm writing in the following manner: opening a file in SD memory and write the content of the buffers I'm using.
This is a minimal example of my attempt:
#include <stdbool.h>
#include "ff.h"
#include <stdio.h>
#include <complex.h>
#include "arm_math.h"
#include "audioMoth.h"
#define NUMBER_OF_SAMPLES_IN_BUFFERS_DATA 4
static float32_t* buffersDATA[12];
int main(void) {
//Create buffers
buffersDATA[0] = (float32_t*)AM_EXTERNAL_SRAM_START_ADDRESS;
for (int i = 1; i < 12; i += 1) {
buffersDATA[i] = buffersDATA[i - 1] + NUMBER_OF_SAMPLES_IN_BUFFERS_DATA;
}
//Example of collected data
float32_t var0[] = {-29.499557,-67.498978,-54.499176,-53.499191};
//Pass collected data to one of created buffers
for (int j = 0; j <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; j+= 1){
*(buffersDATA[0]+j) = var0[j];
}
//Initialize file system
AudioMoth_enableFileSystem();
// Write text file
FIL fpt;
f_open(&fpt,"dataVAR.txt", FA_CREATE_ALWAYS | FA_WRITE);
for (int i = 0; i <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; i+= 1){
char str[8];
sprintf(str, "%d, ", (int)var0[i]);
f_puts(str,&fpt);
}
f_close(&fpt);
// Write another text file
FIL fptr;
f_open(&fptr,"data.txt", FA_CREATE_ALWAYS | FA_WRITE);
for (int i = 0; i <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; i+= 1){
char str[8];
sprintf(str, "%d, ", (int)*(buffersDATA[0]+i));
f_puts(str,&fptr);
}
f_close(&fptr);
}
Typecasting is because sprintf does not support float values, but integer is enough for me to know if I am doing OK or not.
When I open dataVAR.txt:
-29, -67, -54, -53,
But data.txt:
0, 0, 0, 0,
when they should be the same.
I've tried the same in a executable (adapting it) to verify that I am correctly passing the values (it seems so).
Where is the problem?
Thanks in advance.

Ok, the problem was that I didn't initialize communication between the microcontroller and the external chip of SRAM.
I did and all worked as expected.

Related

Can't create ppm File from an executable (C)

I am trying to create a ppm file from inside a C program, but somehow it doesn't work.
It works fine when I am inside the IDE and run the program there. The program is executed and the file created inside the file's folder.
But once I build it and open the executable with a double click, the program runs in the terminal but does not create the file.
I am working on a mac and this is the relevant code, thanks in advance you all!
// from generalSettings.h
#define WIDTH 1100
#define HEIGHT 966
#define MYFILENAME "testimage.ppm"
int pictureArray[HEIGHT][WIDTH];
//from the main.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "generalSettings.h"
int main()
{
triangle firstParentTriangle;
// these two functions "draw" sierpinsky triangles in the pictureArray
drawFirstParentTriangle(&firstParentTriangle);
drawChildTriangles(firstParentTriangle, numberOfRecursions);
create_ppm();
return 0;
}
void create_ppm()
{
unsigned char color_black[] = "000 000 000\n";
unsigned char color_white[] = "255 255 255\n";
FILE *p_file = fopen(MYFILENAME, "w");
if (NULL != p_file)
{
fprintf(p_file, "P3\n %d %d\n 255\n", WIDTH, HEIGHT);
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
if (1 == pictureArray[i][j])
fprintf(p_file, color_black);
else
fprintf(p_file, color_white);
fclose(p_file);
}
}
Here, I have replaced the foreground and background variables with local ones.
Generally, the program inserts 1 to the pictureArray[][] on certain elements and leaves others with a 0.
For my problem, this should be the relevant code for a reproducable example.
EDIT: Problem solver. File was created in the user folder due to missing path.

C: variables retain the value from previous operation instead of resetting

I am fairly new to C and have been trying my hand with some arduino projects on Proteus. I recently tried implementing a keypad and LCD interface with Peter Fleury's libraries, so far the characters I input are displayed fine, but I run into a problem when trying to print to the serial port. It's like the value of the keys keeps on being concatenated with every iteration so the ouput has extra characters like this:
The value before the comma is from the 'key' variable, the value after it the 'buf' variable:
151
(The 5 I input in the second iteration was added to the 1 from the first iteration and then put into the variable I print)
I figure it may be due to my lack/incorrect use of pointers, heres is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>
#include "lcd.h"
#include "mat_kbrd.h"
#include "funciones.h"
#include "menu.h"
char buf[256];
char* coma = ",";
int main(void)
{
pin_init();
serial_begin();
lcd_init(LCD_DISP_ON);
kbrd_init();
bienvenida();
while (1) {
int i = 0;
char key = 0;
//char *peso;
//int pesoSize = 1;
char peso[100];
//peso = calloc(pesoSize,sizeof(char));
int salida = 0;
lcd_clrscr();
desechos();
key = kbrd_read();
if (key != 0) {
lcd_gotoxy(0,3);
lcd_putc(key);
_delay_ms(2000);
lcd_clrscr();
cantidad();
while (salida != 1) {
char keypeso = 0;
keypeso = kbrd_read();
//pesoSize = i;
//peso = realloc(peso,pesoSize*sizeof(char));
if (keypeso != 0) {
if (keypeso == '+') {
salida = 1;
keypeso = *("");
lcd_clrscr();
calcularTotal(key,peso);
_delay_ms(2000);
} else {
lcd_gotoxy(i,1);
lcd_putc(keypeso);
snprintf(peso, sizeof peso, "%s%s",peso, &keypeso);
//strcat(peso,&keypeso);
i++;
_delay_ms(2000);
}
}
}
snprintf(buf, sizeof buf, "%s%s%s", &key,coma,peso);
serial_println_str(buf);
}
}
}
&key and &keypeso point to a single char, but you are using the %s format specifier, so trying to read a string into a single char. Use %c rather then %s for single characters, and pass the char not the address-of-char..

How to create a txt file from FOR loop?

I wrote a C++ code using iterative methods. For this, I used a FOR loop. However, I need to save every result by iteration in same text file (or DATA file) as a columns. How can I do it? Thanks for your advices.
This a simple version of my code:
#include <iostream>
#include <conio.h>
#include <iomanip>
using namespace std;
int i;
main()
{
cout<<"Value 1"<<right<<setw(20)<<"Value 2"<<endl;
for(i=0;i<5;i++)
{
cout<< left << setw(20) << i+10
<< setw(20) << i<<endl;
}
getch();
}
For most purposes using a CSV file would be better. Here is a code that does what you need.
#include <stdio.h>
int main() {
FILE * fpw; // A file pointer/handler that can refer to the file via a cpp variable
fpw = fopen("data.txt", "w"); // Open the file in write("w" mode
if (fpw == NULL) {
printf("Error"); // Detect if there were any errors
return 0;
}
fprintf(fpw, "Value 1,Value 2\n"); // Write the headers
int i = 0;
for (i = 0; i < 5; i++) {
fprintf(fpw, "%d,%d\n", i + 10, i); // Write the values
}
fclose(fpw); //Don't forget to close the handler/pointer
return 0;
}
Output:
A file data.txt will be created with following contents:
Value 1,Value 2
10,0
11,1
12,2
13,3
14,4

C - Reading from a file and saving the info on a variable

im having a problem reading from these 2 files bellow, file1 and file2, and then saving their information in 2 variables.
From the file1 i want to save the name of channels, and from the file2 i want to save the name of the users and the channel where they are signed.
I was thinking of creating 2 typedef struct(shown bellow) and then create 2 variables(shown bellow) and open the files and put the info on those lists.
I also know of another way to do it which is making a 2D array like this char[100][100], the only problem with both these solutions is that I have to impose an upper limit on the amount of the channels the list/array has.
Im not sure if these are the best ways to do it or if there is a better and easier way to do it, could you guys help?
If you guys need any more information just say so, Thanks!
Edit1: i've added the read from the file1 code that i have right now and i think it is working or so it seems but my problem/question was more of is it the right way to save the information to a variable or is there a better/easier way to do it? thanks.
Channel channels[MAX_CHANNELS];
Registration registrations[MAX_REGISTRATIONS];
typedef struct{
char name_channel[20];
int id;
} Channel;
typedef struct{
char username[50];
char name_channel[20];
} Registration;
File1:
General
SO
PCD
FBD
File2:
2016-09-26 14:00:01 paul General
2016-09-26 14:01:11 mary SO
2016-09-27 10:33:17 paul SO
2016-09-27 13:32:10 rachel General
2016-09-27 13:32:12 rachel FBD
code to read the file(i have only done the file1 yet).
File *file1 = fopen("channels.txt", "r");
if(file1==NULL){ perror("Reading error: "); exit(1); } ;
char line[100];
int i = 0;
int w=0;
for(w;w<MAX_CHANNELS;w++){
channels[w].id=-1;
strcpy(channels[w].name, "n");
}
while(fgets(line, 100, file1) != NULL){
printf("Line read: %s", line);
line[ strlen(line) -1 ] = 0;
Channel a;
strcpy(a.name , line);
a.id=1;
channels[i]=a;
i++;
}
fclose(canais);
int k;
for(k=0; k<MAX_CHANNELS; k++){
if(channels[k].id!=-1)
printf("testing var with channels: %s\n", channels[k].name);
}
Just a few tips that might help(in the code comments) :) I think its fine the way you are doing it. I think this is extensible as well since you can add a new member to a struct if you want to enrich you data further. I have seen strtok used to parse through data quite a bit. Strtok should eliminate the need for you to overwrite the newline due to the way it works.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MYSTRINGLEN (50) // In general "magic numbers"
//in code makes it hard to read, though these are fairly apparent,
//but try using #define where you can
typedef struct {
char name[MYSTRINGLEN];
// int id;
}Channel;
typedef struct {
char username[MYSTRINGLEN];
char name[MYSTRINGLEN];
} Registration;
int main(int argc, char *argv[]){
int i = 0;
//int w = 0; not needed
int k = 0;
char line[100];
Channel channels[BUFSIZ] = {{{0}}}; // num of brackets depends on num of nested data structure
Registration registrations[BUFSIZ] = {{{0}}};
/* init all to zero instead w/ bracket syntax
for (w = 0; w < BUFSIZ; w++){
channels[w].id = -1;
strcpy(channels[w].name, "n");
}
*/
FILE * file1 = fopen("channels.txt", "r");
//Many people use strtok to get done what you are doing here if you are interested
while(fgets(line,100,file1)){ // do not need to explicitly state NULL
printf("Line read %s\n", line);
line[strlen(line) -1] = 0;
//Channel a; You have already initialized a whole array of struct, just use them
strcpy(channels[i].name, line);
//a.id = 1;
//channels[i]=a;
i++;
}
fclose(file1);
for(k = 0; k < BUFSIZ; k++){
if (0 != channels[k].name[0]){ //can test if string was populated, dont need id flag
printf("testing var with channels: %s\n", channels[k].name);
}
}
return 0;
}
de here

Using KissFFT on a wave file

I am trying to use the KissFFT Library with this 11 second 44kHz .wav sample file as a test input.
However as I process the file with a window size of 512, I am getting only 1 output value. Which is weird, the 11 sec .wav file at 44kHz should not give 1 value as an output with a windows size of 512. A smaller windows like 16 would give me 5 values, which is still a low count.
Does anyone know what I am doing wrong?
This is my code:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#define WIN 512
int main()
{
char *music_file = "C:/MSin44W16-13.wav";
FILE *in;
char buf[WIN * 2];
int nfft = WIN, i, fx;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
in = fopen(music_file, "r");
if (!in) {
printf("unable to open file: %s\n", music_file);
perror("Error");
return 1;
}
fx = 0;
while (fread(buf, 1, WIN * 2, in))
{
for (i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
free(cfg);
scanf("%d");
return 0;
}
This is the output I get:
42.7577
This is the Updated Code version, but I am getting errors at compile:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#include "sndfile.h"
#define WIN 512
int main()
{
char *music_file = "C:/voice.wav";
SNDFILE *infile;
SF_INFO sfinfo;
//int readcount;
short buf[WIN * 2];
int nfft = WIN;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
if (!( infile = sf_open(music_file, SFM_READ, &sfinfo) ))
{ /* Open failed so print an error message. */
printf("Not able to open input file %s.\n", "input.wav");
/* Print the error message fron libsndfile. */
sf_perror(NULL);
return 1;
}
while ((sf_read_short(infile, buf, WIN)))//fread(buf, 1, WIN * 2, in)
{
//system("cls");
for (int i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
sf_close(infile);
free(cfg);
int temp;
scanf_s("%d", &temp);
return 0;
}
I followed the steps on this post:
"error LNK2019: unresolved external symbol" error in Visual Studio 2010
And I still get these errors:
The problem does not comes from KissFFT, but rather from the fact that you are trying to read a binary wave file opened in ASCII mode on the line:
in = fopen(music_file, "r");
As you later try to read data with fread you eventually hit an invalid character. In your specific sample file, the 215th character read is the Substitute Character (hex value 0x1A), which is interpreted as an end of file marker by your C runtime library. Correspondingly, fread stops filling in more data and eventually return 0 (at the second iteration with WIN set to 512 and a little later with WIN set to 16).
To get around this problem, you should open the file in binary more with:
in = fopen(music_file, "rb");
Note that this will ensure the binary data is read as-is into your input buffer, but would not decode the wave file header for you. To properly read and decode a wave file and get meaningful data in, you should look into using an audio library (such as libsndfile to name one). If you must roll your own wave file reader you should read the specifications and/or check out one of many tutorials on the topic.

Resources