Hidrólisis del agua con PWM (HHO vehicular)

Hola amigos.
COMO PUEDO GENERAR UNA FRECUENCIA DE 32 Mhz O SUPERIOR CON UN ARDUINO LEONARDO? QUIERO USAR digitalWrite COMO EN EL SKETCH BLINK.
CORRIJANME SI ES NECESARIO AMIGOS. MODIFIQUE EL wiring.c #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(1 * 256))PERO LOGRO APENAS 67.49 Khz EN EL PIN 13 CON digitalWrite(13, HIGH)... delayMicroseconds(1).
ALGUN LUGAR HABLA DE USAR "nop" PERO NO COMPRENDO SI EN EL SKETCH O MODIFICANDO EL wiring.c...
asm("nop\n\t");

asm("nop\n\t""nop\n\t""nop\n\t""nop\n\t");

GRACIAS POR SU AYUDA, EN REALIDAD SOY NUEVO EN TODO LO QUE TIENE QUE VER CON ARDUINO.

QUIERO USAR EL LEONARDO COMO CONTROL DE UN MOSFET TOSHIBA 2SK1542 EN UNA CELDA SECA PARA PRODUCIR HHO E INSTALARLO EN UN AUTOMOVIL

GRACIAS NUEVAMENTE.

Lastima los ojos solo de abrirlo

Hola felipeacelas.

  1. Escribir en mayúsculas es GRITAR!!!. Entonces nada de mayúsculas.

  2. Lee las normas del foro.

  3. Física pura, dime como harías para que un microcontrolador que usa un cristal de 16Mhz genere consumiendo ciclos de reloj, una onda cuadrada de 32Mhz.
    Si lo logras, paténtalo.

Ahora fuera de la ironía de mi comentario. Es imposible.
Soluciones POSIBLES.
Usando algun PLL o un DDS externo que llegue a dicha frecuencia.

  1. Todo código va usando [ code ] y [ / code ] sin los espacios. Es el tag nro 19

Luego si encontraste algun enlaces usa el tag 11 y publícalo para que sepamos de que hablas.

  1. La mejor solución es como te dije usar un DDS Direct Digital Synthesis
    El AD9850 te permite generar todo tipo de señales, senoidales, cuadradas, triangulares, propias, hasta 40Mhz desde 0Hz.
    Creo que satisface bien tu necesidad.

Mira este ejemplo pero debe haber muchos mas
Aca la librería para usarlo DDS AD9850 Library

Y acá tienes un tutorial que resume su uso

Gracias mil Surbyte.
Tu consejo y ayuda son muy valiosas para mi.
Es realmente satisfactorio experimentar la ayuda de quienes tienen el conocimiento, la personalidad y el don de compartir lo que realmente nos inmortaliza... El Conocimiento compartido.

A max-saeta... nada mas que disculpas... no pretendi insultar a nadie con mi ignorancia.

Dios les bendiga y llene sus manos con paz, amor, prosperidad y salud en compañia de sus seres amados.

Creo que no me veran mas por estos lados.

ahh te salvaste, yo soy creo que el mas duro con los mensajes en mayúsculas pero como Max te llamó la atención no quise ser reiterativo.

Hablar en mayúsculas es GRITAR.

No te ofendas.. nadie intenta ofender a nadie.
Como estamos sin moderador no podemos controlar ciertas cosas asi que los mas activos intentamos mantener esto ordenado

Saludos
No fue ofensa sino que ni termine de leerlo porque esta todo en mayúscula. En serio lastima mis ojos.

Bueno, si no entiende los comentarios nada podemos hacer.
Como dije y Max lo repite, nadie intenta ofender.
Yo soy en general mas duro con muchos usuarios nuevos, pero reconozco que Max es mas sutil que yo.
De todos modos siempre se intenta ayudar y hacer entender que hay reglas que cumplir y hacer respetar.

Dejemos esto atras y sigamos con el proyecto.

Disculpen la sensibilidad.
es mi primer foro.
ya quedo comprendido que no puedo lograr 32Mhz si fisicamente solo tengo un cristal de 16Mhz.
Pero al menos puedo aproximarme a estos 16 Mhz???
La placa es Leonardo R3, probe con un sketch que encontre en otro foro pero al verificarlo, sale error tras error y no lo carga.
*/
#ifndef PRESCALER_INC
#define PRESCALER_INC

#include "WProgram.h"

/**

  • Prescaler division
    */
    #define CLOCK_PRESCALER_1 (0x0)
    #define CLOCK_PRESCALER_2 (0x1)
    #define CLOCK_PRESCALER_4 (0x2)
    #define CLOCK_PRESCALER_8 (0x3)
    #define CLOCK_PRESCALER_16 (0x4)
    #define CLOCK_PRESCALER_32 (0x5)
    #define CLOCK_PRESCALER_64 (0x6)
    #define CLOCK_PRESCALER_128 (0x7)
    #define CLOCK_PRESCALER_256 (0x8)

// Initialize global variable.
static uint8_t __clock_prescaler = (CLKPR & (_BV(CLKPS0) | _BV(CLKPS1) | _BV(CLKPS2) | _BV(CLKPS3)));

inline void setClockPrescaler(uint8_t clockPrescaler) {
if (clockPrescaler <= CLOCK_PRESCALER_256) {
// Disable interrupts.
uint8_t oldSREG = SREG;
cli();

// Enable change.
CLKPR = _BV(CLKPCE); // write the CLKPCE bit to one and all the other to zero

// Change clock division.
CLKPR = clockPrescaler; // write the CLKPS0..3 bits while writing the CLKPE bit to zero

// Copy for fast access.
__clock_prescaler = clockPrescaler;

// Recopy interrupt register.
SREG = oldSREG;
}
}

inline uint8_t getClockPrescaler() {
return (__clock_prescaler);
}

inline uint16_t getClockDivisionFactor() {
return ((uint16_t)(1 << __clock_prescaler));
}

/**

  • Time in milliseconds.
  • NOTE: This is the equivalent of the millis() function but it readjusts it according
  • to the current clock division. As such, be careful of how you make use of it, in
  • particular remember it will be wrong if the clock division factor is changed during the
  • course of computation. Remember that you can reset the overflow counter by calling the
  • init() function from wiring.h.
    */
    inline unsigned long trueMillis()
    {
    return millis() * getClockDivisionFactor();
    }

// Waits for #ms# milliseconds.
// NOTE: Please see comment above.
inline void trueDelay(unsigned long ms)
{
unsigned long start = trueMillis();
while (trueMillis() - start < ms);
}

/**

  • Rescales given delay time according to division factor. Should be called before a call
  • to delay(). Insures compatibility with function using delay().
  • Example use:
  • delay( rescaleDelay(1000) ); // equivalent to wait(1000)
    */
    inline unsigned long rescaleDuration(unsigned long d) {
    return (d / getClockDivisionFactor());
    }

/**

  • Rescales given time (in milliseconds or microseconds) according to division factor. Should
  • be called
    */
    inline unsigned long rescaleTime(unsigned long t) {
    return (t * getClockDivisionFactor());
    }

#endif

otro sketch desactiva las interrupciones incluso de la comunicacion y por poco no logro que mi pc reconociera de nuevo el leonardo pues aparecia como dispositivo usb desconocido.

con digitalWrite() solo he logrado 70.40 Khz en los pines 5 y 6.

gracias por su ayuda.

Saludos.
No tampoco podrás acercarte a los 16MHz del reloj, cada instrucción de maquina seria aproximadamente 4 ciclos de reloj, pero usando un lenguaje mas elevado como el C++ del arduino cada instrucción sencilla como while (trueMillis() - start < ms); toma muchas lineas de maquina, por lo tanto muchos mas ciclos del reloj.

Tienes que probar con las interrupciones por temporizado y comprobar que frecuencias te entregran, y hacer toda la programacion en ASM

la instruccion nop es una instruccion asembler que significa no operation osea no hacer nada es una operacion que no tiene ningun resultado, es solo para perder un ciclo de reloj, sive para hacer rutinas de tiempos muy precisas.

Pero para eso que quieres hacer tu no tiene sentido, ya que tu micro perderia muchisimo tiempo solo para hacer parpadear un led a altas frecuencias.
Para ello lo mejor es usar pwm, y enviar esa señal a un pll. con el cual multiplicas la frecuencia recibida.
O simplemente usa un oscilador externo

gracias max.
ese lenguaje esta fuera de mi alcance...
realmente soy un novato autodidacta.
pense usar arduino para evitarme armar engorrosos circuitos que ademas serian mas costosos, leonardo en mi pais costo apenas unos U$15, crei que era una copia china pero lo trajo un amigo de italia desde un vendedor directo. hacer un circuito con componentes podria valer unos U$80 o U$90... gran diferencia.
por esto acudi al foro.
cree que alguien pueda ayudarme escribiendo el programa que requiero???

mil gracias por su comprencion y consejos.

hola maxid.
gracias por unirte a mi causa muy personal por demas.

le explico a max porque me acerque a arduino...
espero me entiendas y quieras seguir ayudandome, por mi parte, me parece muy interesante esta herramienta y empesare a estudiarlo mas profundamente, mi trabajo se relaciona con la industria de la inyeccion de plantas (suelas o pisos) para calzado y se me ocurren innumerables aplicaciones... pero debo trabajar en aprender a programar... por ahora, este proyecto personal me apasiona y quisiera verlo marchando asi parezca un zangano...

gracias de nuevo a todos. de corazón gracias.

QUIERO USAR EL LEONARDO CON UN MOSFET TOSHIBA 2SK1542 EN UNA CELDA SECA PARA PRODUCIR HHO E INSTALARLO EN UN AUTOMOVIL

No entiendo que quieres hacer? Eso siempre debería explicarse bien en el primer hilo y vamos y venimos luego de varios dias y seguimos atascados.

Primero el objetivo, intenta describirlo bien, y si hay alguno video mejor aún.
Gracias.

QUIERO USAR EL LEONARDO CON UN MOSFET TOSHIBA 2SK1542 EN UNA CELDA SECA PARA PRODUCIR HHO E INSTALARLO EN UN AUTOMOVIL

Bueno esa parte no la leí. y vaya que es peligroso!!!

Te recomiendo antes de que explotes o mates a otros con eso estudies bien.

Y como dice Surbyte, explica primero bien que hacer despues se sigue con el tema y si este ultimo es otro tema pues abres otro hilo.

Ya entendí, quiere hacer una celda de energía.
Generar una separación de Hidrógeno y Oxígeno para su vehículo.
Supuestamente con una frecuencia X se logra una eficiencia en la separación de H2 y O2 mucho mayor que con una DC.

Que pasó con el link del AD9850 Direct Digital Synthesis que te pasé, cuesta 20 dolares, no es tanto.

Mira esto, 300 pesos en Argentina son 34 dolares y quitale un 30% porque siempre son caros los gatos de aduana, asi que 23.80 dolares el módulo puede costar o menos.

Modulo AD9850

Hasta me gustó para mis proyectos.

gracias surbyte, en Colombia no se consigue comercialmente, el envio desde Argentina unos U$45 o U$50; como ves se sube demasiado.
por otra parte, ya hice pruebas con la celda seca de hho y logre buenos resultados, mi objetivo ahora es como lo dices, optimizar le eficiencia con la frecuencia obtenida desde el arduino como control de la etapa de potencia proporcionada por el mosfet.

Como te saqué el objetivo jajaja!!!
Recuerdo hace muchos años haber leído que era un secreto justamente la frecuencia a la cual se logra hasta 7 veces mas desprendimiento de H2 y O2 que en condiciones de electrólisis normal.
Sabes cual es la frecuencia?

Frecuencia para una electrolisis eficiente

bueno ahora que me empape parcialmente en el tema debo preguntarte porque quieres llegar a 40Mhz cuando en teoría (puedo estar equivocado) te alcanza con 48.2Khz?

Por lo que veo el mayor problema no es generar la PWM sino ya que en un momento se calientan las placas se debe bajar la corriente para compensar eso, de modo que necesitas un lazo de control, estoy en lo correcto?

Hola Surbyte.

gracias por tu ayuda.

tienes razón, en lo de los 48.2 Khz; creo que en mi investigación, tome el valor que aparecía allí sin revisar las unidades u otras fuentes.
esa frecuencia ya la logre con creses... 70.4 Khz, ahora logre hallar en otra fuente donde logra disminuir la corriente (que para el caso de mi celda es de 22A a 25 A) y producir 1.7 lpm consumiendo apenas 4.5A. Como imaginaras, menor corriente es menor consumo de potencia y por tanto menor producción de calor; eso lo logran con dc pulsante, 48.2 Khz con intervalo de 1 Khz.

encontre algo parecido en la web:

const byte LED = 9; // Timer 1 "A" output: OC1A

ISR (TIMER2_COMPA_vect)
{
TCCR1A ^= _BV (COM1A0) ; // Toggle OC1A on Compare Match

if ((TCCR1A & _BV (COM1A0)) == 0)
digitalWrite (LED, LOW); // ensure off

} // end of TIMER2_COMPA_vect

void setup() {
pinMode (LED, OUTPUT);

// set up Timer 1 - gives us 38.095 MHz (correction: 38.095 KHz)
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV (CS10); // CTC, No prescaler
OCR1A = 209; // compare A register value (210 * clock speed)
// = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095

// Timer 2 - gives us our 1 mS counting interval
// 16 MHz clock (62.5 nS per tick) - prescaled by 128
// counter increments every 8 uS.
// So we count 125 of them, giving exactly 1000 uS (1 mS)
TCCR2A = _BV (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
TIMSK2 = _BV (OCIE2A); // enable Timer2 Interrupt
TCCR2B = _BV (CS20) | _BV (CS22) ; // prescaler of 128

} // end of setup

void loop()
{
// all done by interrupts
}

pero no he logrado cargarlo en mi arduino leonardo,
error en la linea:
TCCR1A ^= _BV (COM1A0) ; // Toggle OC1A on Compare Match

y como ya le explique, no tengo conocimientos profundos en la programación o si simplemente este sketch no es para mi placa.

Ahora leí el link que me envió, el voltaje correcto entre placas está en el orden de los 1.4 vdc a los 1.7 vdc mas tensión disminuye la corriente pero incremente la producción de calor. +calor=++vapor de agua= ««hho.
gracias de nuevo.

A ver. Lo que leí sobre el tema es que arrancas con un consumo de corirente y la celda comienza a calentar el agua además de generar H2 y O2, y al calentar tiende a aumentar la corriente porque disminuye la impedancia (resistencia que ofrece a la PWM).

He leido mucha palabrería sobre el tema, por lo visto muchos creen ver la veta de oro produciendo H2 pero no es tarea fácil.

Por otro lado lo único que debes hacer es: Generar tu PWM de 48.2Khz que ya la lograste.
Luego usando un sensor de corriente como el ACS712 de 30 Amper o 50A según decidas cual usar, medir la corriente. Eso habrá que estudiarlo porque es una PWM, pero nada que no pueda resolverse.

F = 48.2Khz son un T (período) de 20.75useg.
habria que estudiar la forma de onda de la corriente para ver que valor tomará el sensor ACS712, pero la corriente eficaz es calculable porque conocemos el tiempo ON y el OFF.
Supongo que tendrá una respuesta capacitiva de carga y descarga.
Una manera de medir la corriente sería tomar muestras del ad a intervalos regulares y luego integrarlos.
Pero a 20.75 useg se complica. Lo primero que recuerdo que el AD del UNO tarda en condiciiones normales 100uS asi que estamos algo lentos.

Hagamos matematicas de Arduino con el AD
El reloj del ADC es 16Mhz dividido el factor del prescaler. El prescaler esta fijado en 128 de modo que (16MHz/128 = 125 KHz) y ya ue la conversión toma 13 ciclos del reloj del ADC entonces 125KHz/13 son 9600 Hz.
O sea que si usamos un prescaler de 16 obtendríamos una tasa de muestreo de alrededor de 77kHz porque 16Mhz/16 = 1Mhz / 13 ciclos = aprox 77 khz

Si nuestra F es de 48.2Khz apenas leeremos 1 muestra lo cual no esta nada bien.

Otra forma de medir la corriente sería usar una resistencia shunt en serie con la carga, agregarle un filtro pasabajos y medir el valor medio.

Toda esta explicación es para leer la coriente, y conforme la leas, ajustas el ciclo de trabajo, reduciendo el Ton lo que bajará el valor medio y mantendrá la temperatura constante o mas o menos.

Hablando de temperatura, esa sería otra manera de hacerlo, sin medir la corriente.

Usar un sensor de temperatura y de nuevo, si se calienta la celda, reduces el Ton del PWM manteniendo siempre tu F de 48.2Khz.