Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos » Arduino y Raspberry Pi
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

30/12/2016 #1

Avatar de Meta

¿Cómo se hace un array de C# a Arduino?
Hola:

Tengo un array tipo byte[] en C# que es este:
Código:
byte[] rawData = {
    0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
    0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43
};
¿Cómo es en Arduino?

Quiero la misma información que el de C#.

¿Cómo se envía por el puerto serie al pulsar un botón esos datos?

Saludos.
30/12/2016 #2

Avatar de Scooter

https://www.arduino.cc
https://www.arduino.cc/en/Reference/String
https://www.arduino.cc/en/Reference/Array

https://www.arduino.cc/en/Reference/Serial
30/12/2016 #3

Avatar de JoaquinFerrero

Código:
unsigned char rawData[] = {
    0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
    0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43
};
30/12/2016 #4

Avatar de Nuyel

Arduino es C++ con las librerías implícitas, se me hace raro que te quedaras sin ideas cuando usas mucho C en otros proyectos.
30/12/2016 #5

Avatar de Meta

JoaquinFerrero dijo: Ver Mensaje
Código:
unsigned char rawData[] = {
    0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
    0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43
};
Tal vez esto sea lo más hacertado, ya que byte[] en C# no lo encontraba en Arduino.

Ahora me falta comprobar como envía por puerto serie esos datos. Para curiiosos hice dos manuales que pueden ver aquí.

http://es.slideshare.net/Metaconta2/...al-studio-2015

http://www.slideshare.net/Metaconta2...al-studio-2015

Y seguiré haciendo más.

Para que vean como curiosidad lo que quiero hacer se lo explico.

Con Photoshop he hecho una tontería de añadir una foto a un bit, como solo me interesa poner "Hola mundo" por probar, lo he hecho pequeño, con la latra del 11 como tamaño y su fuente "Arial Bold".


Lo guardé en gif y pesa solo desde Photoshop 141 bytes, al guardarlo en el disco duro dice pesar algo más grande como 1.197 bytes, ha crecido, así que no me interesa. Lo guardé esta vez nombre.wbm y ocupa 139 bytes, tal como indica Photoshop, no hay aumento por ningún tipo como el.gif.

La imagen que vez abajo es el que digo, en este caso está en gif y el que usaré es .wbm.


Teniendo en cuenta el espacio del Arduino UNO memoria programa o flash, de unos 32 KB, el bootloader de 500 Byte más otros tantos bytes de tu propio programa, pues 139 bytes parece que no, pero puedo alargarlo.

Con la misma técnica un archivo .png más grande me ocupa 1.621 bytes, si lo pongo en esta ocasión en wbm me ocupa unas 5 KB, increible. En este ejemplo un png.


Puedo meter en el TAmega328P más todavía de información cuando me sobre.

Para los que les pica la curiosida. ¿Cómo se consigue los bytes de una imagen?
En C# como ejemplo se hace así:

Se coge la imagen con el editor hexadecimal, en este caso HxD gratuito, se selecciona todo.


Luego pegas dentro del IDE dicha variable. Con Arduino eslo mismo.


Todo esto sin cifrar, que se puede hacer desde Arduino o simplemente ya lo metes cifrado desde otro programa creado por ti o por terceros, así que al pasar los datos al disco duro desde Arduino, no saben lo que es. Esto es ya otra curiosidad. Como curiosidad o para que se hagan una idea, puedes hacerlo simplemente cifrar una imagen así con XOR.

Código:
    for (int i = 0; i < rawData.Length; i++)
    {
        rawData[i] = (byte)(rawData[i] ^ 10);
    }
En resumen, curiosidad.
31/12/2016 #6

Avatar de Scooter

El puerto serie tiene un buffet fifo de 64 bytes, creo. Si tu cadena es menor que eso, sencillamente lo "lanzas" y él solo ya se envía. Si es mayor debes de llevar cuidado en no desbordarlo

Enviado desde mi 5056D mediante Tapatalk
31/12/2016 #7

Avatar de Meta

Buenas Scooter:

Si no recuerdo mal, ese buffer es del puerto serie virtual, no el físico.

Para que te hagas una idea. Un vídeo que estáen el disco duro sacado deun Blu-Ray, puede pesar 50 GBy tengo la RAM de8 GB de mi PC, en el disco duro, tiene un buffer de64 MB por nombrar alguno, no se como estarán ahora. Los datos se pasan por flujos, poco a poco.

Siguiendo con el tema, con el ejemplo de apagar y encender un Led, voy a modificarlo.
Código:
// Enviar tramas de byte al puerto serie.

int estadoBoton=0; // Guardará el estado del botón HIGH o LOW.
int anteriorBoton=0;
char caracter;
String comando;
int flagMensaje=0;

void setup()
{
  pinMode(13,OUTPUT); // Donde está el Led 13.
  pinMode(8,INPUT); // Entrada digital donde está el pulsador.
  Serial.begin(115200);
}

void loop()
{
    estadoBoton=digitalRead(8); // Leer entrada digital número 8.
    
    // Si el pulsador está pulsado, se enciende el Led 13 y
    // envía comando HIGH por el puerto serie.

    if(estadoBoton != anteriorBoton) // Comprueba si ha habido un cambio en el estado del botón.
    { 
      flagMensaje = 0;                // Resetea la bandera a 0.
      anteriorBoton = estadoBoton;    // Guarda el estado actual del botón.
    }

 if (estadoBoton == HIGH && flagMensaje == 0) // Comprueba que el botón esté pulsado y que no se haya enviado el mensaje.
    {
      digitalWrite(13,HIGH);
      Serial.write("ON");
      delay(50);
     
      if(flagMensaje == 0)  // Si se envío el mensaje aumenta la variable a 1 para no enviarlo la próxima vez.
        flagMensaje++;
    }
    
 // De lo contrario, Led 13 epagado y envía LOW al puerto serie.
 else if(flagMensaje == 0) // Si el botón no está presionado y aún no se envía el mensaje.
    {
      digitalWrite(13,LOW);
      Serial.write("OFF");
      delay(50);
     
      if(flagMensaje == 0) // Si se envió el mensaje aumenta la variable en 1 para no enviarla la próxima vez.
        flagMensaje++;
    }
}
Hay que meter el código que nos dió nuestro compañero que es este en el Arduino.
Código:
unsigned char rawData[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43 };
Código modificado y con errores, ya empezamos.
Código:
// Enviar tramas de byte al puerto serie.

int estadoBoton=0; // Guardará el estado del botón HIGH o LOW.
int anteriorBoton=0;
char caracter;
String comando;
int flagMensaje=0;
unsigned char rawData[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43 };

void setup()
{
  pinMode(13,OUTPUT); // Donde está el Led 13.
  pinMode(8,INPUT); // Entrada digital donde está el pulsador.
  Serial.begin(115200);
}

void loop()
{
    estadoBoton=digitalRead(8); // Leer entrada digital número 8.
    
    // Si el pulsador está pulsado, se enciende el Led 13 y
    // envía comando HIGH por el puerto serie.

    if(estadoBoton != anteriorBoton) // Comprueba si ha habido un cambio en el estado del botón.
    { 
      flagMensaje = 0;                // Resetea la bandera a 0.
      anteriorBoton = estadoBoton;    // Guarda el estado actual del botón.
    }

 if (estadoBoton == HIGH && flagMensaje == 0) // Comprueba que el botón esté pulsado y que no se haya enviado el mensaje.
    {
      digitalWrite(13,HIGH);
      // Serial.write("ON");
      Serial.write(rawData); // Enviar imagen o foto hacia el puerto serie al PC.
      delay(50);
     
      if(flagMensaje == 0)  // Si se envío el mensaje aumenta la variable a 1 para no enviarlo la próxima vez.
        flagMensaje++;
    }
    
 // De lo contrario, Led 13 epagado y envía LOW al puerto serie.
 else if(flagMensaje == 0) // Si el botón no está presionado y aún no se envía el mensaje.
    {
      digitalWrite(13,LOW);
      Serial.write("OFF");
      delay(50);
     
      if(flagMensaje == 0) // Si se envió el mensaje aumenta la variable en 1 para no enviarla la próxima vez.
        flagMensaje++;
    }
}
Errores:
Arduino:1.8.0 (Windows 10), Tarjeta:"Arduino/Genuino Uno"

C:\Users\Meta\Documents\Arduino\Enviar_foto_puerto \Enviar_foto_puerto.ino: In function 'void loop()':

Enviar_foto_puerto:34: error: call of overloaded 'write(unsigned char [24])' is ambiguous

Serial.write(rawData); // Enviar imagen o foto hacia el puerto serie al PC.

^

C:\Users\Meta\Documents\Arduino\Enviar_foto_puerto \Enviar_foto_puerto.ino:34:27: note: candidates are:

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232:0,

from sketch\Enviar_foto_puerto.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:129:20: note: virtual size_t HardwareSerial::write(uint8_t) <near match>

virtual size_t write(uint8_t);

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:129:20: note: no known conversion for argument 1 from 'unsigned char [24]' to 'uint8_t {aka unsigned char}'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:130:19: note: size_t HardwareSerial::write(long unsigned int) <near match>

inline size_t write(unsigned long n) { return write((uint8_t)n); }

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:130:19: note: no known conversion for argument 1 from 'unsigned char [24]' to 'long unsigned int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:131:19: note: size_t HardwareSerial::write(long int) <near match>

inline size_t write(long n) { return write((uint8_t)n); }

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:131:19: note: no known conversion for argument 1 from 'unsigned char [24]' to 'long int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:132:19: note: size_t HardwareSerial::write(unsigned int) <near match>

inline size_t write(unsigned int n) { return write((uint8_t)n); }

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:132:19: note: no known conversion for argument 1 from 'unsigned char [24]' to 'unsigned int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:133:19: note: size_t HardwareSerial::write(int) <near match>

inline size_t write(int n) { return write((uint8_t)n); }

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:133:19: note: no known conversion for argument 1 from 'unsigned char [24]' to 'int'

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232,

from sketch\Enviar_foto_puerto.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:49:12: note: size_t Print::write(const char*) <near match>

size_t write(const char *str) {

^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:49:12: note: no known conversion for argument 1 from 'unsigned char [24]' to 'const char*'

exit status 1
call of overloaded 'write(unsigned char [24])' is ambiguous

Este reporte podría tener más información con
"Mostrar salida detallada durante la compilación"
opción habilitada en Archivo -> Preferencias.

Le añadí esta instrucción.
Código:
Serial.write(rawData);
Pues da error el de arriba.

Añadí el byte de la imagen y me ocupa en memoria esto:
El Sketch usa 3534 bytes (10%) del espacio de almacenamiento de programa. El máximo es 32256 bytes.
Las variables Globales usan 212 bytes (10%) de la memoria dinámica, dejando 1836 bytes para las variables locales. El máximo es 2048 bytes.


Feliz año viejo 2016.
31/12/2016 #8

Avatar de Scooter

Si, claro, el buffer del puerto serie es por software, del "sistema operativo" del arduino. Los microcontroladores que conozco tienen un byte de buffer, solo en usarts dedicadas he visto buffers fifo en hardware, aunque puede que algún microcontrolador tenga.

No estoy muy puesto con el manejo de arrays, me parece que seria.write solo admite 1 byte, tendrás que hacer un bucle que lea el array y envíe todos los archivos
31/12/2016 #9

Avatar de cosmefulanito04

Scooter dijo: Ver Mensaje
No estoy muy puesto con el manejo de arrays, me parece que seria.write solo admite 1 byte, tendrás que hacer un bucle que lea el array y envíe todos los archivos
Y entre cada envío, agregar el insustituible delay!

Código:
...
  Serial.write(rawData);
  Thread.sleep(10);
...
31/12/2016 #10

Avatar de Meta

Buenas:

Estoy probado ahoramismo el Visual Studio para Arduino, la deventaja que el VMicro de pago tiene de bugger, con lo que ayuda esto, para saber los datos de cada variable y donde se mueve el programa, porque el Arduino IDE es muy malo y lento.

http://www.luisllamas.es/2015/12/el-...-visual-micro/

Siguiendo el tema.
Hablarás de este for.


https://www.arduino.cc/en/Reference/For

Lo de enviar array por el puerto serie parace ser que es así.
Código:
char myarray[sizeofarray];
........

for(n=0; n < sizeofarray; n++)
{

serial.print(myarray[n]);
// Con su delay(10);
}
http://forum.arduino.cc/index.php?topic=16651.0
http://panamahitek.com/serial-arduin...nas-2da-parte/

Espero que el buffer no me toque las narices.

Sigo investigando...
31/12/2016 #11

Avatar de cosmefulanito04

No creo que haga falta agregar ese delay, solo molestaba al anti-delay del foro.

Meta, fijate si tenés un método (función) en C# que envíe directamente arrays de bytes, seguramente ya está implementado eso.
31/12/2016 #12

Avatar de Scooter

Si, delay hay que poner. Si no, no vale
Incluso hay que poner un delay dentro del delay, claro.

No se muy bien si avisa cuando se va a desbordar el buffer give pruebas con un display 4x20 que no cabía todo de golpe, pero no me acuerdo de que pasaba si se desbordaba.

Cuando era pequeño hice uno con el 8052 con 128 bytes de buffer de entrada y otros tantos de salida y ahí si que habían banderas que avisaban cuando estaba vacío, lleno etc.

Lo hice así para usar punteros de 8 bits en la RAM externa-interna de at89c51...
Enviado desde mi 5056D mediante Tapatalk
31/12/2016 #13

Avatar de cosmefulanito04

Se suele usar colas circulares, se usa dos índices, uno que indique el último bytes recibido y otro el último bytes leído.

Sería algo así:

Código:
#define TAMANIO_BUFFER 32

unsigned char buffer_rx[TAMANIO_BUFFER];
unsigned char indice_rx=0, indice_lectura=0;

... rutina_interrupcion_uart_rx()
{
   buffer_rx[indice_rx]=registro_dato_uart_rx;
   indice_rx++;

   if(indice_rx==TAMANIO_BUFFER )
     indice_rx=0;   
}

....

... rutina_de_lectura_datos_uart_rx()
{
   if(indice_rx<indice_lectura) //La recepción de datos pego la vuelta en la cola circular
   {
      for(; indice_lectura<TAMANIO_BUFFER; indice_lectura++)
      {
         TomoAccionConDatoRecibido(buffer_rx[indice_lectura]);
      }

      indice_lectura=0; //Reseteo el contador de lectura
   }
   
   for(; indice_lectura<indice_rx; indice_lectura++)
   {
       TomoAccionConDatoRecibido(buffer_rx[indice_lectura]);
   }   

   if(indice_lectura==TAMANIO_BUFFER) //Un posible reseteo el contador de lectura
     indice_lectura=0; 
}
Y algo similar habría que hacer en caso de querer una colar circular de transmisión.
31/12/2016 #14

Avatar de Meta

Hola:

No se si hay que usar un delay por medio o no. Me parece que no, de todas formas lo probaré con y sin delay haber que pasa.

Parece que enviarlatrama del array es esta.
Código:
// creo que sizeof(rawData) debería dar correctamente el tamaño del array porque lo definiste como unsigned char
// sino debe usarse de este modo sizeof(rawData)/sizeof(unsigned char *) para obtener el valor correcto

for (uint8_t i=0; i<sizeof(rawData); i++) {  // supongo que son menos de 255 elementos
    Serial.write(rawData[i]);
}
Otra forma como se hace.

Código:
Serial.write(rawData, sizeof(rawData));
El Sketch usa 5152 bytes (15%) del espacio de almacenamiento de programa. El máximo es 32256 bytes.
Las variables Globales usan 1826 bytes (89%) de la memoria dinámica, dejando 222 bytes para las variables locales. El máximo es 2048 bytes.
Poca memoria disponible, se pueden producir problemas de estabilidad.

Por lo que veo, debo de alguna forma, poner todos esos byte en la memoria Flash y que me deje la RAM que se gaste todo de golpe.
31/12/2016 #15

Avatar de Scooter

Mejor prueba a ver, porque si pruebas haber no va a ir seguro.

El buffer ya lo tiene de serie el sistema del arduino que yo sepa no se puede modificar.
Creo que recordar que sencillamente se para hasta que haya hueco, es decir, si envías 63 bytes la ejecución es sencillamente "inmediata" y cuando sea se van enviando. Si envías mas, la ejecución se para hasta que quepan en el buffer.
Simplemente puedes probar esto un
digital.write (el_pin_que_sea,high)
serial.print("poner una cadena de 63 bytes")
digital.write (el_pin_que_sea,low)
y con un osciloscopio medir el ancho de pulso

Hacer lo mismo con mas bytes a ver si aumenta sustancialmente ...

es mas, mirando los tics del sistema debería de poderse ver.
Hay la función milis() y micros() para medir tiempos
31/12/2016 #16

Avatar de locodelafonola

Hola ., bueno desde entrada., se que me van a retar ., pero lo digo igual
Y tambien se que no se lo suficiente ., perooooo
Por enpezar saca W10 de tu maquina (hay recursos que consume en segundo plano)., que son grandicimos ., volve al W7
Segundo ., si ya que vas a usar arduino ., hacelo desde el AVRstudio (ultima vercion)
Si hubieras tenido esa vercion ., ya te hubieras enterado ., como se hace eso que intentas hacer (ayuda en linea ., recursos ., ejemplos)
Esta explicado por aca ., que justamente es el atmega328 ., es el que tiene mas ejemplos http://ee-classes.usc.edu/ee459/library/
Por aca la libreria de ejemplo
Código PHP:
/***************************************************************************
 *   Copyright (C) 2015 by Tobias Müller                                   *
 *   Tobias_Mueller@twam.info                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>

enum format_t xbmtwam };

struct bitmap_t {
    
int32_t width;
    
int32_t height;
    
unsigned int rowwidth;
    
uint16_t depth;
    
unsigned char *data;
};

int read_bitmap_from_file(const charfilenamestruct bitmap_tbitmap) {
    
int ret 0;
    
FILE *fd;
    
charbuffer;
    
char header[54];
    
unsigned short offset;
    
unsigned char bottomup;
    
unsigned int align;

    
// open file
    
if ((fd fopen(filename"r")) == NULL) {
        
fprintf(stderr"Error while opening file '%s'.\n"filename);
        
ret = -1;
        goto 
read_bitmap_ret;
    }

    
// read header
    
if (fread(headersizeof(char), 54fd) != 54) {
        
fprintf(stderr"File '%s' is not a valid Windows Bitmap! (Header too short)\n"filename);
        
ret = -2;
        goto 
read_bitmap_fclose;
    }

    
// check signature
    
if ((header[0] != 0x42) || (header[1] != 0x4D)) {
        
fprintf(stderr"File '%s' is not a valid Windows Bitmap! (Wrong signature: 0x%X%X)\n"filenameheader[0], header[1]);
        
ret = -3;
        goto 
read_bitmap_fclose;
    }

    
// offset where image data start
    
offset = (header[11] << 8) | header[10];

    
// read width from header, should be positiv
    
bitmap->width = *(int32_t*)(header+18);

    
// read height from header
    
bitmap->height = *(int32_t*)(header+22);

    
// Is this a bottum up picture?
    
bottomup bitmap->height >= 0;

    
// color depth of image, should be 1 for monochromes
    
bitmap->depth = *(uint16_t*)(header+28);

    
// width of a byte row
    
if (bitmap->width 8) {
        
bitmap->rowwidth = ((bitmap->width/8)+1) * bitmap->depth;
    } else {
        
bitmap->rowwidth = (bitmap->width/8) * bitmap->depth;
    }

    
// 4-byte alignment width of a byte row, align >= bitmap->rowwidth
    
if (bitmap->rowwidth 4) {
        
align = ((bitmap->rowwidth 4)+1)*4;
    } else {
        
align bitmap->rowwidth;
    }

    
fprintf(stdout"File '%s' is a %ix%ix%i bitmap\n"filenamebitmap->widthbitmap->heightbitmap->depth);

    if (
bitmap->depth != 1) {
        
fprintf(stderr"File '%s' is not an 1-bit Bitmap!\n"filename);
        
ret = -4;
        goto 
read_bitmap_fclose;
    }

    
// jump to offset
    
fseek(fdoffsetSEEK_SET);

    if ((
bitmap->data = (unsigned char*)malloc(align*bitmap->height)) == NULL) {
        
fprintf(stderr"Could not aquire memory for image data (%u bytes)!\n"align*bitmap->height);
        
ret = -5;
        goto 
read_bitmap_fclose;
    }

    if ((
buffer = (char*)malloc(align)) == NULL) {
        
fprintf(stderr"Could not aquire memory for read buffer (%u bytes)!\n"align);
        
ret = -6;
        
free(bitmap->data);
        goto 
read_bitmap_fclose;
    }

    for (
unsigned int row=0row<bitmap->height; ++row) {
        
fseek(fdoffset+row*alignSEEK_SET);

        
// get char by char
        
for (unsigned int col =0col <= align; ++col) {
            
buffer[col] = fgetc(fd);
        }

        if (
bottomup) {
            
memcpy(bitmap->data+(((bitmap->height-1)-row)*bitmap->rowwidth), bufferbitmap->rowwidth);
        } else {
            
memcpy(bitmap->data+(row*abs(bitmap->width/8)), bufferbitmap->rowwidth);
        }

    }

    
free(buffer);

read_bitmap_fclose:
    
fclose(fd);

read_bitmap_ret:
    return 
ret;
}

void print_binary(char bunsigned char length) {
    if (
length == 0length 8;
    
int i;
    for (
i=7i>=8-lengthi--) {
        if (
& (1<<i)) {
            
printf("X");
        } else {
            
printf(".");
        }
    }
}

void print_bitmap(struct bitmap_tbitmap) {
    for (
unsigned row=0row<bitmap->height; ++row) {
        
printf("%3i ",row);
        for (
unsigned int col 0col<bitmap->rowwidth; ++col) {
            
print_binary(bitmap->data[row*bitmap->rowwidth+col], col == bitmap->rowwidth -bitmap->width 8);
        }
        
printf("\n");
    }
}

// write as standard xbm
int write_bitmap_as_xbm(const charfilenamestruct bitmap_tbitmap, const charname) {
    
int ret 0;
    
FILE *fd;

    
// open file
    
if ((fd fopen(filename"w")) == NULL) {
        
fprintf(stderr"Error while opening file '%s'.\n"filename);
        
ret = -1;
        goto 
write_bitmap_xbm_ret;
    }

    
fprintf(fd"#define %s_width %u\n"namebitmap->width);
    
fprintf(fd"#define %s_height %u\n"namebitmap->height);
    
fprintf(fd"static char %s_bits[] = {\n"name);

    for (
unsigned int line 0line <= (bitmap->height*bitmap->rowwidth)/12; ++line) {
        
fprintf(fd"\t");

        
unsigned int max_pos = (line < (bitmap->height*bitmap->rowwidth)/12) ? 12 : (bitmap->height*bitmap->rowwidth) % 12;

        for (
unsigned int pos 0pos max_pos; ++pos) {
            
unsigned char data 0;

            
// change LSB<->MSB
            
for (unsigned int bit 0bit 8; ++bit) {
                if (
bitmap->data[line*12+pos] & (<< bit)) {
                    
data |= (<< (7-bit));
                }
            }

            
fprintf(fd"0x%02X, "data);
        }

        if (
line == (bitmap->height*bitmap->rowwidth)/12) {
            
fprintf(fd"};");
        }

        
fprintf(fd"\n");
    }

    
fclose(fd);

write_bitmap_xbm_ret:
    return 
ret;
}

// write twam's own format
int write_bitmap_as_twam(const charfilenamestruct bitmap_tbitmap, const charname) {
    
int ret 0;
    
FILE *fd;

    
// open file
    
if ((fd fopen(filename"w")) == NULL) {
        
fprintf(stderr"Error while opening file '%s'.\n"filename);
        
ret = -1;
        goto 
write_bitmap_twam_ret;
    }

    
fprintf(fd"bitmap_t PROGMEM %s = { "name);
    
fprintf(fd"%u, "bitmap->width);
    
fprintf(fd"%u, "bitmap->height);
    
fprintf(fd"{\n");

    for (
unsigned int line 0line <= (bitmap->height*bitmap->rowwidth)/12; ++line) {
        
fprintf(fd"\t");

        
unsigned int max_pos = (line < (bitmap->height*bitmap->rowwidth)/12) ? 12 : (bitmap->height*bitmap->rowwidth) % 12;

        for (
unsigned int pos 0pos max_pos; ++pos) {
            
unsigned char data 0;

            
// change LSB<->MSB
            
for (unsigned int bit 0bit 8; ++bit) {
                if (
bitmap->data[line*12+pos] & (<< bit)) {
                    
data |= (<< (7-bit));
                }
            }

            
fprintf(fd"0x%02X, "data);
        }

        if (
line == (bitmap->height*bitmap->rowwidth)/12) {
            
fprintf(fd"}");
        }

        
fprintf(fd"\n");
    }
    
fprintf(fd"\t};\n");

    
fclose(fd);

write_bitmap_twam_ret:
    return 
ret;
}

int main(int argccharargv[]) {
    
enum format_t format twam;
    
struct bitmap_t bitmap;

    if (
argc != 4) {
        
printf("You need to call: %s <inputfile> <outputfile> <imagename> \n",argv[0]);
        
printf("  e.g. %s input.bmp image.h image\n",argv[0]);
        return 
1;
    }

    
// read bitmap
    
if (read_bitmap_from_file(argv[1], &bitmap)<0) {
        
fprintf(stderr"Error while opening file '%s'!\n"argv[1]);
        exit(
EXIT_FAILURE);
    }

    
// print bitmap
    
print_bitmap(&bitmap);

    switch (
format) {
        case 
xbm:
            
write_bitmap_as_xbm(argv[2], &bitmapargv[3]);
            break;
        case 
twam:
            
write_bitmap_as_twam(argv[2], &bitmapargv[3]);
            break;
    }

    
// clean up bitmap
    
free(bitmap.data);

return 
0;

La descarga completa lo tenes por aca
https://github.com/twam/bmp2hex
Y si queres aca te subo un conversor de imagenes a archivo .HEX
Ahora si queres un archivo mas livianito., y muy parecido a lo que que queres hacer., tenes esto
Código PHP:
/*
  bmp2hex - Converts a 1-bit/pixel image in a BMP image file into hexadecimal
  data for use in initializing a C or assembler program data array.

  Only works on 1-bit/pixel images, and probably not on all of those.

  Allan Weber, USC Dept. of Electrical Engineering, 11/7/06
*/

#include <stdio.h>
#include <stdlib.h>

// #define DEBUG

unsigned char fileheader[14];
unsigned char infoheader[40];

main(int argcchar *argv[])
{
    
int offsetwidthheightbitcount;
    
int nwidthbytespadbytes;
    
unsigned char *img, *p;
    
int rowcolchinvert;
    
extern int optind;
    
extern char *optarg;

    
invert 0;

    while ((
ch getopt(argcargv"i")) != -1) {
    switch (
ch) {
    case 
'i':
        
invert 1;
        break;
    case 
'?':
        
usage();
        exit(
1);
    }
    }

    if (
fread(fileheader114stdin) != 14) {
    
fprintf(stderr"Error reading fileheader\n");
    exit(
1);
    }
    if (
strncmp(fileheader"BM"2) != 0) {
    
fprintf(stderr"File is not BMP format\n");
    exit(
1);
    }
    if (
fread(infoheader140stdin) != 40) {
    
fprintf(stderr"Error reading fileheader\n");
    exit(
1);
    }

    
/* Get some numbers from the headers */
    
offset get4(fileheader 10);
    
width  get4(infoheader 4);
    
height get4(infoheader 8);
    
bitcount get2(infoheader 14);
    
#ifdef DEBUG
    
printf("offset=%d, width=%d, height=%d, bitcount=%d\n",
       
offsetwidthheightbitcount);
#endif

    /* Skip over any color table */
    
offset - (14 40);
    if (
0)
    
fseek(stdinnSEEK_CUR);

    
/* Check to make sure it's 1-bit per pixel */
    
if (bitcount != 1) {
    
fprintf(stderr"Unsupported bit depth - %d\n"bitcount);
    exit(
1);
    }

    
widthbytes = (width 7) / 8/* number of data bytes per line */
    
padbytes = ((width 31) / 32) * 4/* data+pad bytes per line */

#ifdef DEBUG
    
printf("widthbytes=%d, padbytes=%d\n"widthbytespadbytes);
#endif

    /* Allocate memory for image data */
    
padbytes height;
    if ((
img malloc(n)) == NULL) {
    
fprintf(stderr"Can\'t allocate memory\n");
    exit(
1);
    }

    
/* Read in image data */
    
if (fread(img1nstdin) != n) {
    
fprintf(stderr"Error reading image data\n");
    exit(
1);
    }

    
/* Loop through image data and print it out */
    
for (row height-1row >= 0row--) {
    
img + (padbytes row);
    for (
col 0col widthbytescol++) {
        
ch = *p++;
        if (
invert
        
ch ^= 0xff;
        
printf("0x%02x, "ch);
    }
    
printf("\n");
    }
}

/* Turn an Intel 4-byte quantity into an 32-bit value */
int get4(unsigned char *p)
{
    
int x;
    
= (*(p+3) << 24) + (*(p+2) << 16) + (*(p+1) << 8) + (*p);
    return(
x);
}

/* Turn an Intel 2-byte quantity into an 32-bit value */
int get2(unsigned char *p)
{
    
int x;
    
= (*(p+1) << 8) + (*p);
    return(
x);
}

usage()
{
    
fprintf(stderr"bmp2hex [-i] < file.bmp\n");

Y mas o menos explicado en el .PDF que te subo ( lo lamento pero esta en ingles)
!!!! suerte y espero que te sirva ¡¡¡¡¡
Archivos Adjuntos
Tipo de Archivo: zip bmp2hex.zip (10,1 KB (Kilobytes), 0 visitas)
Tipo de Archivo: pdf BinaryImage.pdf (94,3 KB (Kilobytes), 1 visitas)
31/12/2016 #17

Avatar de Meta

Gracias.
Ahora estoy ocupado por el fin de año.

La comunicación del RS232 en este caso es asíncrona.

Hay que llenar el buffer hasta los 64 bytes.
Enviar esos 64 bytes.
Almacenar el índice del array.
Borrar el buffer.
Mirar el índice del array donde estaba antes.
Continuar donde terminó para volver a llenar el buffer otros nuevos 64 bytes.
Almacena otra vez el índice posición 128 del array.
Vuelve a enviar otros 64 byte de la tramas de byte de rawData.
Vuelve a borrar el buffer a 0.
Así hasta que acabe todos los datos.

Es lo que creo.
Aún así debe haber una forma de no llenar toda la RAM solo con el array rawData.

Feliz año viejo 2016.
31/12/2016 #18

Avatar de Scooter

El buffer se borra solo no hay que hacer nada con él

Sabiendo la velocidad de transmisión se puede poner un pause , perdón buscar una actividad para esperar a que se transmitan y

Y si, W10 no mola y W7 tampoco. Linux forever .

Enviado desde mi 5056D mediante Tapatalk
31/12/2016 #19

Avatar de Meta

Ya me encargaré en meterme con Linux también.
Solo esperar al próximo año para seguir...
01/01/2017 #20

Avatar de Meta

Por lo que cuenta en este enlace, puedo usar diractamente la memoria flash en vez de la RAM, así que no tendré problemas.

¿Para que sirve?

  • PROGMEM hace que una variable constante a la que se le aplica resida en la memoria flash en vez de la RAM. Asi podemos ahorrar RAM para las demás variables.
  • Si tenemos muchos strings que no se tienen que modificar (por ejemplo strings de menus) vale la pena guardarlos en la flash para que no ocupen RAM
  • Las variables PROGMEM tienen espacio asignado en la memoria que no cambia durante la ejecución del programa.


http://wiki.erikcrane.net/index.php/PROGMEM

Voy averiguar como se usa correctamente.

Les comentaré según siga avanzando.

Feliz año nuevo 2017.

Edito:
Haciendo pruebas al compilar:
Código:
unsigned char rawData[] = {
El Sketch usa 5152 bytes (15%) del espacio de almacenamiento de programa. El máximo es 32256 bytes.
Las variables Globales usan 1826 bytes (89%) de la memoria dinámica, dejando 222 bytes para las variables locales. El máximo es 2048 bytes.
Poca memoria disponible, se pueden producir problemas de estabilidad.

Código:
PROGMEM const unsigned char rawData[] = {
El Sketch usa 5154 bytes (15%) del espacio de almacenamiento de programa. El máximo es 32256 bytes.
Las variables Globales usan 206 bytes (10%) de la memoria dinámica, dejando 1842 bytes para las variables locales. El máximo es 2048 bytes.

Ahora si que estoy tranquilo, ya que como me queda mucho de lamemoria Flash, pues puedo poner una imagen mucho más grande.

Sigo experimentando.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Buscar más temas sobre:
Lupa Arduino y Raspberry Pi

Cerrar
Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos » Arduino y Raspberry Pi

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.