Symple JavaScript applet.

Simple JavaScript applet to do some calculations in a webpage:

```html
	<br />
	This is a JS applet example.<br />
	<br />
	Set "A" value and choose "Multiplier".<br />
	<br />
	Click on "Calculate" to perform the operation.<br />
	<br />
	<hr />
	<br />
	<div>
	  <script>

		function mult(form)
		{
		  var valA = form.A.value;
		  var valM = form.M.value;
		  
		  form.AxM.value = valA*valM;
		}
	  </script> <br />
	<br />
	<form name="multiply">
	<br />
	Number A: <input name="A" style="background-color: white; width: 100px;" value="0" /><br />
	<br />
	Multiplier : <select name="M" style="background-color: white; width: 100px;" value="2">
					 <option value="2">x2</option>
					 <option value="4">x4</option> </select> <br />
	<br />
	<input name="Calc" onclick="mult(this.form)" style="width: 100px;" type="button" value="Calculate" />  <br />
	<br />
	<hr />
	<br />
	A x Multiplier = <input name="AxM" style="width: 95px;" value="" /> <br />
	<br />
	<br />
	<br /></form>
	</div>
```


This is how it looks:
--------------------------------------------------

This is a JS applet example.

Set "A" value and choose "Multiplier".

Click on "Calculate" to perform the operation.






Number A:

Multiplier :





A x Multiplier =



Integer to any base QString

This function takes an integer and returns a QString with the representation in any base < 16.

It uses the val2hex function from previous post:
.....................................................................................................
```c
QString val2hex( int d )
{
    QString Hex="0123456789ABCDEF";

    QString h = Hex.mid( d&15, 1 );

    while( d>15 )
    {
        d >>= 4;
        h = Hex.mid( d&15,1 ) + h;
    }
    return h;
}

QString decToBase( int value, int base, int digits )
{
    QString converted = "";

    for( int i=0; i= base ) converted = val2hex(value%base) + converted;
        else                converted = val2hex(value) + converted;

        value = floor( value/base );
    }
    return converted;
}
```
.....................................................................................................

Integer to Hex QString

This function takes an integer and returns a QString with the exadecimal representation:
.....................................................................................................
```c
QString val2hex( int d )
{
    QString Hex="0123456789ABCDEF";

    QString h = Hex.mid( d&15, 1 );

    while( d>15 )
    {
        d >>= 4;
        h = Hex.mid( d&15,1 ) + h;
    }
    return h;
}
```
.....................................................................................................

File to QString

Read a file and parse whole content to a QString:
.....................................................................................................
```c
QString fileToString( const QString &fileName, const QString &caller )
{
    QFile file( fileName );

    if( !file.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::warning( 0l, caller, 
                              "Cannot read file "
                              +fileName+":\n"
                              +file.errorString());
        return "";
    }

    QTextStream in( &file );
    QString text = in.readAll();
    file.close();

    return text;
}
```
.....................................................................................................

File to QStringList

Read a file and parse each line to a QStringList:

.....................................................................................................

```c
QStringList fileToStringList( const QString &fileName, const QString &caller )
{
    QStringList text;
    QFile file(fileName);

    if( !file.open( QFile::ReadOnly | QFile::Text) )
    {
        QMessageBox::warning( 0l, caller, 
                              "Cannot read file "
                              +fileName+":\n"
                              +file.errorString());
        return text;
    }

    QTextStream in( &file );
    while( !in.atEnd() ) text.append( in.readLine() );
    file.close();

    return text;
}
```

.....................................................................................................

Add entry to QListWidget and resize to content

Sometimes is useful resizing a QListWidget to the size of its content.
This is one way to do it.

Don't forget resizing again when you remove an item.

.....................................................................................................

```c
void addEntry( QString name, QListWidget* list )
{
    QListWidgetItem* item = new QListWidgetItem( name, list, 0 );
  
    QFont font;
    font.setPointSize(10);
    font.setWeight(70);
    item->setFont( font );

    item->setIcon( QIcon(":/icon.png") );
       
    int iconSize = 22;                       // I know icon size

    int size = list->count()*iconSize + 2;

    list->setFixedHeight( size );
}
```

.....................................................................................................

Wemos to InfluxDB via Wifi

This is a simple example of how to send data from a Wemos board to InfluxDB  throught wifi.

Tested with Wemos D1 R2 and Arduino IDE.

You should change ssid, password to your wifi.
Also InfluxDB database name and data you are using.

.....................................................................................................

```c
#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>

#define USE_SERIAL // Comment this line for no serial

const char* ssid = "Your_SSID";
const char* password = "Your_Pass";

ESP8266WiFiMulti WiFiMulti;

void setup()
{
    #ifdef USE_SERIAL
    Serial.begin( 115200 );
    #endif

    WiFi.mode( WIFI_STA );
    WiFiMulti.addAP( ssid, password );
}

void loop()
{
    if( WiFiMulti.run() == WL_CONNECTED ) // wait for WiFi connection
    {
        int sensorValue = analogRead( A0 );
       
        // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 3.2V):
        float voltage = sensorValue * (3.2/1023.0);
       
        #ifdef USE_SERIAL
        Serial.println( voltage );
        #endif
       
        HTTPClient http;

        #ifdef USE_SERIAL
        Serial.print( "[HTTP] begin...\n" );
        #endif
       
        // Start writting to influxbd database: mydb
        // Set database, IP and Port you are using
        http.begin( "http://192.168.1.33:8086/write?db=mydb" );
  
        // Send data to influxbd
        // Set data you are using
        int httpCode = http.POST( "Volts,Bat=Lead-Acid,Ser=pruebas value="+String(voltage) );
       
        #ifdef USE_SERIAL
        if(httpCode == 204) // Data Succesfully Written
        {
            Serial.printf( "Data Succesfully Written... code: %d\n", httpCode );

        }
        else // Data Failed
        {
            Serial.printf( "Data Failed... code: %d\n", httpCode );
            Serial.printf( "Error: %s\n", http.errorToString(httpCode).c_str() );
        }
        #endif
       
        http.end();
    }

    delay( 10000 ); // Wait for 10 seconds
}
```

.....................................................................................................

AVR Software PWM

One way to do software pwm is setting up a timer with interrupt corresponding to each pwm step. then in the interrupt routine check whether each pwm channel should be on or off.

The key question here is how fast and how many steps should be the PWM.
All depends in how much processing time you need for other tasks, and how many PWMs to run.

A good aproach that works for me is doing a 64 steps, 200 uS per step PWM for around 50 PWM channels.
This give us a total time of 50*200=12800 uS = 12.8 mS => 78.125 Hz.
Getting less than 10% of processing time.

I ussually do it with Timer0, this creates a 200 uS Timer0 CompA Interrupt.
I think it works for most AVR, but you can choose the part you need depending on wich registers your mcu uses:

```c
// For 16 MHz clock

#define T0Top_Avr 50
#define T0PresAvr 3

   #if defined( OCR0 )
      OCR0  = T0TOP_Avr;
      TCCR0 = 64 + TMR0PresAvr; // CTC mode: TOP = OCR0
   #elif defined( OCR0A )
      OCR0A  = T0TOP_Avr;
      TCCR0A = 2;               // CTC mode: TOP = OCR0A
      TCCR0B = TMR0PresAvr;
   #endif
  
   // enable Timer 0 compare_A interrupt
   #if defined( TIMSK0 )
      TIMSK0 = 0;
      TIMSK0 |= (1 << OCIE0A);
   #elif defined( TIMSK )
      TIMSK = 0;
      TIMSK |= (1 << OCIE0A);
   #endif
  
   sei();      // Enable interrupts



// Now in the interrupt routine:

#define numPWM 32             // Number of PWM Channels
uint8_t pwmChannel[ numPWM ]; // Array containing pwm values
uint8_t pwmCounter=0;

ISR(TIMER0_COMPA_vect)        // Timer 0 compare_A interrupt
 { 
    for( uint8_t i=0; i pwmCounter ) 
        {
            // Set the output line "i" HIGH
            // This depends on the hardware you are using
        }
        else
        {
            // Set the output line "i" LOW
        }
    }
    pwmCounter++;
    if( pwmCounter > 63 ) pwmCounter = 0;
{ 
```

USBaspLoader: Bootloader por USB sin ftdi

USBaspLoader es un bootloader por USB para microcontroladores AVR con al menos 2 KB flash de memoria para bootloader, por ejemplo los populares ATMega8, 168 y 328.

La ventaja es que no necesita ningún chip conversor USB-Serie ni ningún otro controlador usb ya que tiene un driver por software basado en V-USB, también de obdev.

Basicamente emula un programador USBasp que se puede usar desde avrdude, de manera que en el host USB se presenta como si hubiéramos conectado un USBasp y se programa normalmente con avrdude, por tanto las placas que lo usen se pueden integrar en el software Arduino seleccionando USBasp como método de programación.
Ejemplo de uso con avrdude para grabar un Atmega328p:

 avrdude -c usbasp -p m328p -u -U flash:w:archivo.hex

Al resetear el micro arranca el bootloader si se cumple cierta condición, normalmente el estado de un pin, que se puede ajustar con un jumper o conmutador; aunque esta condición es configurable si se editan y compilan las fuentes; si no se cumple la condición se ejecuta normalmente el programa grabado en la sección baja de la flash.

Este bootloader se puede grabar al chip con cualquier programador ICSP, pero antes hay que ajustar los fuses correctamente, esta información se puede encontrar en el makefile del firmware, por ejemplo para Atmega328 a 16 MHz:

lfuse: 0xF7
hfuse: 0xDA
efuse: 0x03

El bootloader lo podéis descargar de aquí: http://www.obdev.at/products/vusb/usbasploader.html Más info sobre V-USB: http://www.obdev.at/products/vusb/index.html

 USBaspLoader permite hacer placas de desarrollo u otros proyectos con un mínimo de hardware y por tanto de costo reducido.

Simulador de Circuitos.

SimulIDE es un simulador de circuitos electrónicos en tiempo real que incluye simulación de microcontroladores PIC y AVR.

ES simple y facil de usar, con una interface gráfica muy limpia en la que no te sentirás sobrecargado por infinidad de opciones y herramientas.
Simplemente eliges componentes, los colocas en el circuito, los conectas y le das al botón de encendido.

La mayoria de las cosas las puedes hacer con el ratón, a veces usando las teclas ctrl o shift.


Tiene un buen número de componentes y en cada versión añaden algunos nuevos.

Dispone de osciloscopio así como de plotter, que se activan con el componente "Probe".

Es de destacar que en la simulación de microcontroladores tienes varias opcione interesantes:

- Monitor serie, para monitorizar comunicaciones por puerto serie primario, pudiendo también enviar datos/ASCII al micro.


- Conectar a un puerto serie en tu computadora, ya sea un puerto serie real como virtual.

- Observar variables y registros del Micro


En resumen, interesante y muy facil de usar simulador, con versiones para Windows y Linux.

Esta es su página web: SimulIDE



Sensor de tempearatura interno Atmega328p

El atmega320P y algunos otros AVR tienen un sensor de tempeartura interna, accesible desde el conversor analógico-digital. Util para detectar sobrecalentamiento.

La precisión no es muy buena en principio, pero se puede calibrar.
Hay una guía de Atmel pra el calibrado: www.atmel.com/Images/doc8108.pdf

Para leer el sensor hay que configurar el ADC con referencia interna de voltaje 1.1 V, y leer el canal 8:

ADMUX = 1100 1000


La conversión a ºC puede variar según condiciones, pero una aproximación podría ser:

ºC = (lectura-325)/1.22


Fast linked list without list

If you need a very fast way to iterate over a list of objects and call the same method on all of them, then here is a posible solution. Der...