¿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.
 
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:
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/apagar-y-encender-led-con-arduino-y-visual-studio-2015

http://www.slideshare.net/Metaconta2/entrada-digital-con-arduino-y-visual-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".
puerto-serie-c-1689739.png


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.
puerto-serie-c-1689740.gif


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.
puerto-serie-c-1689745.png


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


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 H:LOL: gratuito, se selecciona todo.
982090


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


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.
 
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

 
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.
 
Última edición:
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
 
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-mejor-ide-para-arduino-visual-studio-con-visual-micro/

Siguiendo el tema.
Hablarás de este for.
ForLoopIllustrated.png


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-arduino-vectores-y-cadenas-2da-parte/

Espero que el buffer no me toque las narices.

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

Meta, fijate si tenés un método (función) en C# que envíe directamente arrays de bytes, seguramente ya está implementado eso.
 
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...
 
Última edición:
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.
 
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.
 
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
 
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​
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 { xbm, twam };

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

int read_bitmap_from_file(const char* filename, struct bitmap_t* bitmap) {
	int ret = 0;
	FILE *fd;
	char* buffer;
	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(header, sizeof(char), 54, fd) != 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", filename, header[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", filename, bitmap->width, bitmap->height, bitmap->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(fd, offset, SEEK_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=0; row<bitmap->height; ++row) {
		fseek(fd, offset+row*align, SEEK_SET);

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

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

	}

	free(buffer);

read_bitmap_fclose:
	fclose(fd);

read_bitmap_ret:
	return ret;
}

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

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

// write as standard xbm
int write_bitmap_as_xbm(const char* filename, struct bitmap_t* bitmap, const char* name) {
	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", name, bitmap->width);
	fprintf(fd, "#define %s_height %u\n", name, bitmap->height);
	fprintf(fd, "static char %s_bits[] = {\n", name);

	for (unsigned int line = 0; line <= (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 = 0; pos < max_pos; ++pos) {
			unsigned char data = 0;

			// change LSB<->MSB
			for (unsigned int bit = 0; bit < 8; ++bit) {
				if (bitmap->data[line*12+pos] & (1 << bit)) {
					data |= (1 << (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 char* filename, struct bitmap_t* bitmap, const char* name) {
	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 = 0; line <= (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 = 0; pos < max_pos; ++pos) {
			unsigned char data = 0;

			// change LSB<->MSB
			for (unsigned int bit = 0; bit < 8; ++bit) {
				if (bitmap->data[line*12+pos] & (1 << bit)) {
					data |= (1 << (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 argc, char* argv[]) {
	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], &bitmap, argv[3]);
			break;
		case twam:
			write_bitmap_as_twam(argv[2], &bitmap, argv[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​
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 argc, char *argv[])
{
    int offset, width, height, bitcount;
    int n, widthbytes, padbytes;
    unsigned char *img, *p;
    int row, col, ch, invert;
    extern int optind;
    extern char *optarg;

    invert = 0;

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

    if (fread(fileheader, 1, 14, stdin) != 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(infoheader, 1, 40, stdin) != 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",
	   offset, width, height, bitcount);
#endif

    /* Skip over any color table */
    n = offset - (14 + 40);
    if (n > 0)
	fseek(stdin, n, SEEK_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", widthbytes, padbytes);
#endif

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

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

    /* Loop through image data and print it out */
    for (row = height-1; row >= 0; row--) {
	p = img + (padbytes * row);
	for (col = 0; col < widthbytes; col++) {
	    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;
    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;
    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 ¡¡¡¡¡
 

Adjuntos

  • bmp2hex.zip
    10.1 KB · Visitas: 2
  • BinaryImage.pdf
    94.3 KB · Visitas: 3
Última edición:
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.
 
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 .

 
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.
 
Última edición:
Atrás
Arriba