Now I'm trying to adapt c code that use files with Arduino ide, So I converted some functions that use with files. but I do not know how to use fgetc() in Arduino ide.
This is the error that I have:
cannot convert 'fs::File' to 'FILE* {aka __sFILE*}' for argument '1' to 'int fgetc(FILE*)'
In function 'PGMData* readPGM(PGMData*)':
read_pgm_image_from_SD:155:18: error: cannot convert 'fs::File' to 'FILE* {aka __sFILE*}' for argument '1' to 'int fgetc(FILE*)'
fgetc(pgmFile);
^
Multiple libraries were found for "SD.h"
Used: C:\Users\lab\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SD
Not used: C:\Program Files (x86)\Arduino\libraries\SD
exit status 1
cannot convert 'fs::File' to 'FILE* {aka __sFILE*}' for argument '1' to 'int fgetc(FILE*)'
This is all my code, I can't print the size of the image, the code inter in loop. The commented line represent the code in c , and it was work (as a c code without any problem). I convert some functions the deal with files to can work on Arduino but the problem I can't get the size of image. any help please?
#include <SD.h>
typedef struct _PGMData {
int row;
int col;
int max_gray;
int **matrix;
} PGMData;
#define HI(num) (((num) & 0x0000FF00) << 8)
#define LO(num) ((num) & 0x000000FF)
int **allocate_dynamic_matrix(int row, int col)
{
int **ret_val;
int i;
ret_val = (int **)malloc(sizeof(int *) * row);
if (ret_val == NULL) {
perror("memory allocation failure");
exit(EXIT_FAILURE);
}
for (i = 0; i < row; ++i) {
ret_val[i] = (int *)malloc(sizeof(int) * col);
if (ret_val[i] == NULL) {
perror("memory allocation failure");
exit(EXIT_FAILURE);
}
}
return ret_val;
}
void deallocate_dynamic_matrix(int **matrix, int row)
{
int i;
for (i = 0; i < row; ++i) {
free(matrix[i]);
}
free(matrix);
}
void SkipComments(File &fp)
{
int ch;
char line[100];
/*
while ((ch = fgetc(fp)) != EOF && isspace(ch)) {
;
}
if (ch == '#') {
fgets(line, sizeof(line), fp);
SkipComments(fp);
} else {
fseek(fp, -1, SEEK_CUR);
}
*/
while (fp.available() && isspace(ch) ){
// Serial.write(fin.read());
ch = fp.read();
}
if (ch == '#') {
// fgets(line, sizeof(line), fp);
int bar=0;
int in_char;
while((in_char = fp.read()) >= 0){
line[bar++] = (char)in_char;
}
SkipComments(fp);
} else {
// fseek(fp, -1, SEEK_CUR);
fp.seek(fp.position());
}
}
//for reading:*
PGMData* readPGM( PGMData *data)
{
File pgmFile;
char version[3];
int i, j;
int lo, hi;
if (!SD.begin(BUILTIN_SDCARD)) {
Serial.println("Failed to mount card read pgm");
}
pgmFile = SD.open("/image.pgm", FILE_READ);
if (!pgmFile) {
Serial.println("Opening file to read failed read pgm");
}
/* if (pgmFile == NULL) {
perror("cannot open file to read");
exit(EXIT_FAILURE);
}*/
/* fgets(version, sizeof(version), pgmFile);
if (strcmp(version, "P5")) {
fprintf(stderr, "Wrong file type!\n");
exit(EXIT_FAILURE);
}
*/
/*
SkipComments(pgmFile);
// fscanf(pgmFile, "%d", &data->col);
SkipComments(pgmFile);
// fscanf(pgmFile, "%d", &data->row);
SkipComments(pgmFile);
// fscanf(pgmFile, "%d", &data->max_gray);
*/
while (pgmFile.available()){
SkipComments(pgmFile);
// fscanf(pgmFile, "%d", &data->col);
data->col = pgmFile.read();
SkipComments(pgmFile);
// fscanf(pgmFile, "%d", &data->row);
data->row = pgmFile.read();
SkipComments(pgmFile);
// fscanf(pgmFile, "%d", &data->max_gray);
data->max_gray = pgmFile.read();
}
/// fgetc(pgmFile);
data->matrix = allocate_dynamic_matrix(data->row, data->col);
if (data->max_gray > 255) {
for (i = 0; i < data->row; ++i) {
for (j = 0; j < data->col; ++j) {
hi = pgmFile.read(); //fgetc(pgmFile);
lo = pgmFile.read(); //fgetc(pgmFile);
data->matrix[i][j] = (hi << 8) + lo;
}
}
}
else {
for (i = 0; i < data->row; ++i) {
for (j = 0; j < data->col; ++j) {
lo = pgmFile.read(); //fgetc(pgmFile);
data->matrix[i][j] = lo;
}
}
}
pgmFile.close();
return data;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial){};
PGMData im;
readPGM( &im);
Serial.print("The size of image = ");
Serial.println(im.col);
Serial.println(im.row);
}
void loop() {
// put your main code here, to run repeatedly:
}
file.read() gets just one character/byte from the file
My suggestions:
I recommend to create a sketch that does only read row and col first. If this runs successfully you can add the rest step by step.
Concentrate on the first x data (10 < x < 80), read and print them via Serial
Analyse the structure (you should recognize where row and col of a known picture are coded
Make sure to correctly read row and col (right place in the file, correct conversion to int)
Good luck!
P.S.: The function fgets is defined as
The C library function **char *fgets(char str, int n, FILE stream) reads a line from the specified stream and stores it into the string pointed to by str . It stops when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first
You can replace it by a routine using file.read() where you read data into a char array until newline has been read, end-of-file or the given limit of n characters has been reached.
The mentioned code in c, and I have the same code in c and work without any problem.
I converted some functions like fgetc() to file.read(). can you check it please if my conversion is correct or not?
And for this line (/// fgetc(pgmFile);) in PGMData* readPGM( PGMData *data)
How can I convert it to work correctly in arduino ide?
Please can you help?
If you google the functions in question you'll find what they do and can replace them either by the corresponding function for file reading or substitute them by a selfmade function.
Both return the next character in the file and increment the "file position indicator" to point the next character in the file (if available).
Check the same for the other functions.
Unfortunately I will not have the time to solve your tasks ... but if you start as I suggested you may get an understanding what you have to do.
Good luck!
Just a hint. If you want other members to assist, it would be a good idea to provide a small pgm file or give a link to the one you use and a link to a description of the file structure. Otherwise you leave the work to get information to the others ...
A more accurate rewrite would look like this, I can't test it or even know if I've got the SD card thing right, but the original reads a character, checks to be sure it got one and if it is a space, ignores it.
while ((ch = fp.read()) != EOF && isspace(ch) ){
; // ignore this space character
}
Which makes me ask if you understood what nd how the original snippet functioned.
In less clever C:
while (1) {
ch = fp.read();
if (ch == EOF) break;
if (!isspace(ch)) break;
}
The SD read() method probably has a return value meaning EOF. If not, there must be some kind of an available() method you could use before reading a character.