mercoledì 8 giugno 2016

IEEE 754

Si tratta di un metodo di memorizzazione di numeri float  con varia lunghezza nel numero di bit (in questo caso sara' utilizzata solo la rappresentazione a 32 bit). Un convertitore on line di numeri in formato IEEE754 puo' esssere trovato a questo link

I bit sono cosi' divisi
1 bit di segno
8 bit di esponente : 2 elevato all'esponente
23 bit : mantissa del numero

In questo formato i numeri 12.5 e 3.5 ottengono la seguente rappresentazione binaria

12.5  0 10000010 10010000000000000000000  1.5625   4718592
3.5    0 10000000 11000000000000000000000  1.75     6291456

il primo bit e' in entrambi i casi 0 perche' i due numeri sono positivi

12.5 puo' essere espresso come 2^3 *1.5625. L'esponente e' quindi 3 ma deve essere sommato il valore di 127 per cui l'esponente e' 127 + 3 = 130d =  10000010b. Infine 10010000000000000000000 e' la rappresentazione binaria di 1.5625

Lo stesso si puo' ripetere per il numero 3.5 che puo' essere espresso come 2^1*1.75

Per sommare i due numeri si procede allineando gli esponenti a quello piu' basso (in questo caso 1). 12.5 viene quindi espresso come 6.25*2^1 (spostando l'esponente di due si moltiplica la mantissa per quattro ovvero 2^spostamento). A questo punto si sommando le mantissa e la somma e' uguale a (6.25+1.75)*2^1 = 8*2=16 ovvero il risultato desiderato (12.5+3.5)

per moltiplicare i due numeri (12.5*3.5=43.75) si procede sommando gli esponenti e moltiplicando le mantisse. In questo caso 2^(1+3)*(1.5625*1.75)=2.734375*2^4. La mantissa deve essere normalizzata perche' e' superiore a 2 per cui il risultato sara' 1.3671875*2^5 ovvero 43.75


Perche' tanto confusione .. perche' ai computer piacciono i numeri a base due ed interi

Questa e' un sistema standardizzato ma esistono altri modi per descrivere un numero. In questo fantastico documento del 1976 a firma tale Roy Rankin e Steve Wozniak sulle procedure matematiche per il 6502 con una rappresentazione a 32 bit nel formato

 Exponent    Two's Complement Mantissa
  SEEEEEEE  SM.MMMMMM  MMMMMMMM  MMMMMMMM
     n         n+1       n+2       n+3

Repository per Yocto su Intel Edison

Come fatto notare in un precedente post, il repository di default opkg di Intel Edison non e' cosi' fornito cosi' si e' abituati per esempio con Arduino YUN.




La soluzione deriva dalle AlexT's Edison Page,   un repository non ufficiale che riporta un discreto numero di pacchetti di uso comune gia' in formato binario

Per abilitare questo repository si deve aggiungere al file /etc/opkg/base-feeds.conf le seguenti righe

-------------------------------
src/gz all http://repo.opkg.net/edison/repo/all
src/gz edison http://repo.opkg.net/edison/repo/edison
src/gz core2-32 http://repo.opkg.net/edison/repo/core2-32
-------------------------------
si digita quindi
opkg update

(sul sito viene esplicitamente indicato di non usare opkg upgrade ma di configurare l'upgrade pacchetto per pacchetto pena la saturazione della rootfs)
Si possono quindi installare pacchetti come opencv e motion senza fatica

lunedì 6 giugno 2016

Moltiplicazione veloce per 10 in binario

Questo e' un sistema rapido per effettuare moltiplicazioni per 10 su un calcolatore binario ripresa da questo documento

L'idea e' quella di dividere la moltiplicazione per 10 come (numero*8)+(numero*2) che equivale ovviamento a numero numero*(8+2). Il vantaggio di questo procedimento e' che in con codificato binario le moltiplicazione per 2 (e per i suoi multipli) consistono semplicemente in uno spostamento verso sinistra dei bit.

Un esempio: moltiplichiamo 123x10
la codifica binaria di 123 e' 1111011
lo shift di un posto (moltiplicazione per due) e' 11110110
lo shift di tre posti (moltiplicazione per otto) e' 1111011000
la somma binaria di 11110110 + 1111011000 equivale a 10011001110 che corrisponde al risultato desiderato di 1230

Il vantaggio di questo sistema e' che in Assembler esiste un comodo apposito per lo shift binario a sinistra che e' ASL nel 6502 e SHL in x86

mercoledì 1 giugno 2016

Sviluppo assembler su C64

Mi e' presa la voglia di tornare alle origini e programmare in assembler sul MOS 6502 (o meglio sul MOS 6510 del Commodore 64). Ovviamente il computer fisico e' in qualche discarica (o spero recuperato) e cerco di usare l'emulatore VICE

In modo, piu' o meno tradizionale, dopo aver avviato l'emulatore, si deve impiegare un assemblatore (nel caso Turbo Assembler per C64...con una curiosa omonimia con TASM Borland per x86) caricando l'immagine di un disco (preventivamente scaricat) con File/Attach Disk Image/Disk 8
con LOAD"$",8 e successivo LIST si ottiene il contenuto del disco


Si carica l'assemblatore con LOAD"*",8,1 ed al READY si digita SYS36864 entrando nella schermata nera di editing. Questo e' il semplice programma di test che stampa a video una stringa


programma in sintassi TASM
--------------------------------------------------
* = $1000

!basic
    ldx #$00
loop  
    lda message,x
    sta $0400,x
    inx
    cpx #$04
    bne loop
    rts
message .text "luca"
--------------------------------------------------

Per compilare il programma si deve usare la combinazione BackArrow+3 ma BackArrow non esiste sulla tastiera PC; si tratta del tasto piu' in alto a sinistra al di sotto del tasto di ESC (che nella tastiera italiana e' il backslash o barra rovescia)




s per start e si avvia il programma. Per rientrare nella fase di editing e' sufficiente ridigitare SYS 36864


E' comunque piuttosto noioso procedere nel modo classico ed e' molto piu' comodo usare C64 Studio (una IDE con allegato ACME un cross compiler 6502) e che permette di eseguire il programma lanciando autonomamente VICE



La differenza sostanziale tra i due metodi e' che usando C64 Studio si deve scrivere un preambolo in Basic che lancia poi il codice Assembler (in pratica una sola linea di codice BASIC che indichi un SYS49152 per passare il controllo al codice assembler...tale preambolo e' ralizzato con le sole righe *=$0801 ovvero la locazione di memoria dove risiede il compilatore BASIC e !basic.. non risulta necessario impostare *=$01000)

programma in sintassi ACME. Da notare come viene dichiarata la stringa
--------------------------------------------------
;set program start address
* = $0801

!basic
    ldx #$00
loop  
    lda message,x
    sta $0400,x
    inx
    cpx #$04
    bne loop
    rts
message !scr "luca"

fra le altre cose con C64 Studio si puo' utilizzare anche direttamente Basic


ArduinoTheremin

Questo progetto e' stata soltanto una occasione per usare la libreria Mozzi e non puo' considerato completo e finito.
Con Mozzi e' possibile trasformare Arduino in un sintetizzatore usando semplicemente il pin 9 ed il Ground collegandoli ai pin di un jack audio da pcb. Fra le altre cose il segnale in uscita e' cosi' alto che puo' essere direttamente mandato in cuffia senza necessita' di amplificazione


L'idea e' quella di usare due sensori ultrasonici SR-04 per controllare la frequenza ed il volume. Il problema e' che Mozzi usa i timer di Arduino per la propria necessita' di produzione audio e quindi SR-04 non e' il componente piu' adatto per interfacciarsi a Mozzi




le frequenze sono scalate da 4 a 40 cm con frequenze da 100 a 660 Hz (la frequenza e' stata poi portata 4 ottave piu' alto) mentre il volume va da 0 al massimo passando da 4 a 40 cm

la base utilizzata deriva da questo sketch
---------------------------------------------------------
/*
This file uses a Ultrasonic Sensor code that was
 modified from the a code found on: 
 http://winkleink.blogspot.ca/2012/05/arduino-hc-sr04-ultrasonic-distance.html
 and modified codes from Mozzi examples and reference documentation.
 */

// Include Mozzi Classes
#include <MozziGuts.h>;
#include <mozzi_config.h>
#include <Oscil.h>;
#include <tables/sin1024_int8.h>;
#include <tables/saw2048_int8.h>;
#include <tables/cos2048_int8.h>;
#include <mozzi_rand.h>;
#include <LowPassFilter.h>;

#define CONTROL_RATE 64

Oscil <2048, AUDIO_RATE> osc(SAW2048_DATA); // Oscilator waveform
Oscil <COS2048_NUM_CELLS, CONTROL_RATE> filterMod(COS2048_DATA); // Low Pass Filter waveform
Oscil <2048, CONTROL_RATE> kvib(SAW2048_DATA); // Vibrato Waveform
LowPassFilter lpf;

// Ultrasonic Sensor Pins
int trigPin = 11;
int echoPin = 12;
// Ultrasonic Sensor Pins
int trigPin2 = 8;
int echoPin2 = 7;

byte volume;

void setup(){
  Serial.begin(115200);
  startMozzi(CONTROL_RATE);
  //lpf.setResonance(20);
  kvib.setFreq(16.5f);
  filterMod.setFreq(1.3f);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
}

void updateControl(){

  // Distance Sensor
  int duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(100);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  int freq = map(distance, 4, 40, 100, 660);
  /*
  C = 261
  C#= 277
  D = 293
  D#= 311
  E = 329 
  F = 349
  F#= 369
  G = 391
  G#= 415
  A = 439
  A#= 466
  B = 493
  C = 523
  */
  
  
  int duration2, distance2;
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(100);
  digitalWrite(trigPin2, LOW);
  duration2 = pulseIn(echoPin2, HIGH);
  distance2 = (duration2/2) / 29.1;
  volume = map(distance2, 4, 40, 0, 255);
  
  byte cutoff_freq = 100 + filterMod.next()/2;
  lpf.setCutoffFreq(cutoff_freq);
  osc.setFreq(freq*2);

  //float depth = 1; // vibrato depth
  //float vibrato = depth * kvib.next();

  /*if (rand(CONTROL_RATE/2) == 0) // Low Pass Filter Frequency
  {
    filterMod.setFreq((float)rand(255)/64);
  }
  byte cutoff_freq = 100 + filterMod.next()/2;
  lpf.setCutoffFreq(cutoff_freq);

  if(xRead > 500){
    osc.setFreq(freq);
  }
  else if(xRead < 500){
    osc.setFreq(freq*4);
  } */
}

int updateAudio(){
  char audio = (lpf.next(osc.next())*volume)>>8;
  return (int) audio;
}

void loop(){
  audioHook(); 
}

lunedì 30 maggio 2016

Foto aeree con Google Carboard

Visto che l'esperimento con gli anaglifi era riuscito ma non nel modo ottimale ho provato a migliorare, questa volta usando un vero stereoscopio,ovvero Google Cardboard, anche se dal costo decisamente economico (uno stereoscopio da tavolo per foto aeree costa sopra il migliaio di euro)


Sul telefono ho montato una semplice pagina web sul telefono Android che scalava e centrava i due fotogrammi precedentemente registrati a mano (in versioni successive sarebbe comodo avere la possibilita' di spostare uno dei fotogrammi via telecomando bluetooh per centrare le immagini guardando nel visore)

Con questo sistema la visualizzazione 3D e' decisamente buona e molto piu' simile a quella del vero stereovisore per foto aeree rispetto a quella anaglifica

index.html
-------------------------
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class ="stereo">
    <div id="sinistra">
      <img alt="Sinistra" title="Sinitra" src="594_2.png" style="width: 100%; max-height: 100%"/>
   </div>
    <div id="destra">
      <img alt="Sinistra" title="Sinitra" src="595_2.png" style="width: 100%; max-height: 100%"/>

   </div>
</div>
</body>
-------------------------

style.css
-------------------------
.stereo{
        width: 100%;
        overflow: hidden;
    }

    #sinistra {
        float: left;
        width: 50%;
    }
   #sinistra img
   {

      margin: auto;
      display: block;
   }
    #destra {
        float: left;
        width: 50%;
    }
   #destra img
   {
      margin: auto;
      display: block;
   }
-------------------------



Foto aeree con anaglifi

A lavoro mi capita spesso la necessita' di visualizzare foto aeree ma non ho un visore stereoscopico. Ho scoperto un sistema semplice (e lecito) per scaricare le stereocoppie dal sito della Regione Toscana (evitando un generoso esborso) e cosi' mi sono messo alla ricerca di un sistema per visualizzare la terza dimensione


Il primo tentativo e' stato quello di utilizzare gli anaglifi mediante l'uso degli occhialini rossi/ciano (qualcuno si ricorda del film lo Squalo 3D??)

Il sistema piu' semplice, una volta scelti i due fotogrammi, e' quello di usare il programma AnaBuilder che permette di coregistrare in automatico le due immagini sia come traslazione che come rotazione dal menu Actions/AutoFit with borders detection


Il risultato non e' male, anche considerando che non c'e' intervento umano, ma il programma riesce a lavorare solo su piccole porzioni della stampa. Introducendo una stampa completa della foto aerea, normalmente in formato 24x24 cm scannerizzata poi a 600 dpi, il programma si blocca.



Il risultato finale e' una immagine blandamente in 3D perche' manda tutta l'esagerazione verticale che fornisce un vero stereoscopio

ps. per scaricare la stereocoppie si puo' andare su Geoscopio, selezionare l'area di interesse, cliccare su Fotogrammi per esempio 2013 (non tutti gli anni hanno la copertura completa del territorio!!) , poi con lo strumento Freccia +, si seleziona uno squadro di un fotogramma e si clicca su visualizza fotogramma. Si ripete il tutto con il fotogramma vicino ed abbiamo una stereocoppia giocando con  poi con i livelli di zoom per avere il dettaglio desiderato. Per rimuovere la finestra della legenda si puo' premere il tasto h (il visualizzatore di immagini e' IIPImage)


Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...