Activate relays with your smartphone (no BT or WiFi, just sounds)

Old smartphones (Pocket PC, Windows Mobile 5 and 6) can be purchased at very low price, and even if old, are really powerful. In addition, you can write and distribute your own applications / games for free, being not in the slavery of “App Markets” of any sort.

In 2009 summer (August and September), I was in France for a “sabbatic” time. I was in city of Albi, relatively far from the sea and the “usual” way to spend summer time (swimming or walking or looking for funny alternatives). France is fantastic for restaurants, aperitives and wine, so that period was very creative for me. The best “fuel” for brain are good food and wines ; if you add that I was are completely alone and without any job duty, you can understand that such condition was very near to the perfection.
Obviously, a minimal “worklab” was part of my baggage: just few things… a solder iron, soldering wire, some indispensable electronic components, a small netbook PC and my smartphone (Samsung SGH-i600). Note that the smartphones like Android and iPhone wasn’t available in that period and the Windows Mobile (5 or 6) was the “modern” OS (surely less intrusive in your privacy than the ones you’re running today). Some time before this journey, I purchased a software tool called PPL (as alternative to Embedded Visual C) and downloaded a free IDE called FBA Creator (you can find a reference to this software gem under my favourite links). I started to realize applications for WM5 / WM6 in the quiet afternoons time, a little step every day. One of the interesting things produced in this learning time, was a program to turn ON/OFF relays using simply DTMF tones played by the phone (under keyboard control). The main idea was to put the phone on a simple “rover” and then write a small webserver to receive commands by any browser, and produce DTMF tones (related to HTTP GET commands) to activate relays, so left and right motors could move the rover and photos taken after every move could be sent via the Internet to my netbook PC. I realized a video that was posted, initially, on youtube. After monster G (Google) acquired youtube, I decided to remove all my videos, ‘cause I was negatively impressed by the growing power of that company, with all the new terms of use of their services ; shorting it, I removed my pages on google space and the videos from youtube. Recently I reloaded some videos on DailyMotion (hoping that this will not be eaten by monster G). If you want take a look at this video, click the player below here and sorry for my horrible english pronuntiation and also for my tragic english writing (NO google translator help, here).


dtmf_remote di robotop

Now, here is the electric diagram of this device. There are 3 relays, the microcontroller (ATMEL ATtiny2313) , one serial interface for  PC connection and analog circuitry to get sounds (thru microphone) and convert them to digital data, by means of specialized decoder IC.

click to enlarge ; PDF copy is included in the downloadable zip

click to enlarge ; PDF copy is included in the downloadable zip

Using this circuit, you can activate / deactivate 3 relays with the DTMF tones emitted by your smartphone / PocketPC. In the downloadable file ef161.zip you can find:
– schematic.pdf , the electric diagram
– dtmf.hex , the Intel-Hex formatted file to burn the micro
– fuses.txt , the fuses configuration used for microcontroller in this application

If you want to take a look at the C source file, click this link
Someone asked me how to indepently control two motors (running CW and CCW) with 3 relays, so here is a state table:

ABC | motor status (0=relay off,as shown in figure; 1=relay ON)
--- | ---------------------------------------------------------
000 | M1 & M2 stop
001 | M1 stop, M2 run clockwise
010 | M1 run clockwise, M2 stop
011 | M1 & M2 run clockwise
100 | M1 & M2 run counterclockwise
101 | M1 run counterclockwise, M2 stop
110 | M1 stop, M2 run counterclockwise
111 | M1 & M2 stop

and a MAD (manually assisted design) schematic…

twomotorsYou can generate DTMF tones directly with your phone keyboard (setting DTMF as default sound for keys) or can use my own program dtmfremote_cab.zip. This one is supplied as CAB compressed in ZIP with a password. Such strange arrangment comes from limitations of the hoster to uploading of executable files. When you download the file, you have to unzip it (the password is: eficara) and then you have the dtmfremote.cab that can be directly installed on your WM5 or WM6 device. Note that my Samsung WM6 phone has a full qwerty keyboard, but not a touch screen, so all the commands are activated using the cursor keys and the OK button. You can also activate a sequence of pre-recorded commands ; such sequence has to be stored in a file called sequence.txt , that must reside on the same working directory of the executable. You can create / edit such file with the default Notepad. On every text row there are two numbers, comma separated (no spaces, please). First number is the bitmap of the 3 relays, so can be a number from 0 to 7 ; a number greater than 7 indicates the end of the sequence (it will loop again from the first row). The second number is the time to wait after setting the relays, prior to jump to next sequence step. This number is expressed in mS (milliSeconds) and can range from 100 to 9999. Lower numbers can’t work, ‘cause the DTMF tone needs for a minimal time to be correctly decoded by hardware.
I also wrote another program to play DTMF, using the free tool FBA Creator ; this application is called fba_dtmf_cab.zip (as usual, is a zipped CAB with password ; you must unzip it using password eficara and have your fba_dtmf.cab ready to be installed on WM5 or WM6 device). The only difference with the previous program (written in PPL) is that the sequence player isn’t included, but the whole working directory, with sources (LUA language) can be downloaded and modified with the FBA tool. IMPORTANT NOTE: if you download and install “FBA the Creator” on Win7 or newer, please create a shortcut to the executable and set this shortcut to be executed by default as administrator. If you don’t do that and launch the executable without administrator rights, you can experience a recursive pop-up error window, that’s very hard to stop. This is just a little problem in a big, genial software, written by an italian author some years ago (in the times of WinXP). Note that all the IDE sources for FBA are also downloadable from the main site. If you look in the forum, you can find some old post by user robotop ; it’s me…

Here is a short presentation video for the FBA IDE I made some time ago for my friends. It’s in Italian, but may be useful just to take a look at the working environment and how it’s easy and powerful (and free…)


FBA-Video_2011-11-23 di robotop

Finally, here is the full working folder (sources and resources) of the DTMF program written under the FBA environment. After downloading the file FBA_folder_dtmf-remote.zip, you must expand it in a directory ; I suggest a new folder under documents, named FBA with subfolders for this and (may be) your future apps. At this point, if you have the FBA environment installed on your PC, just click the file dtmfrem.fbp to start the IDE and… happy mobile phone programming 🙂

View a short video of this application running in the IDE default emulator…


dtmfrem di robotop

FreeBasic + FireFly = ambiente di sviluppo visuale Windows gratuito

Ho ricevuto un messaggio tramite il relativo form su una pagina del vecchio sito. Rispondo pubblicamente in quanto la richiesta è interessante… Chi mi scrive ha usato con successo il FreeBasic per convertire vecchi programmi da GW-Basic e altri “dialetti” Basic. Tutti questi programmi, per ora, girano nella solita “finestra DOS” e così mi si chiede se io possa suggerire un modo semplice per scrivere qualcosa che funzioni come una qualsiasi applicazione Windows. Personalmente, utilizzo a questo scopo l’ambiente IDE gratuito chiamato FireFly. Ho aggiunto un link sulla colonna a destra (links utili) per poterne fare il download. L’ambiente di sviluppo si integra perfettamente con FreeBasic e il risultato è ottimo. Le applicazioni scritte sono assolutamente “eleganti” e ricordo che si tratta di eseguibili completi, non serve alcuna “runtime”. Io utilizzo la FIREFLY_FB_350 che è liberamente scaricabile dal sito dell’azienda produttrice. Questa versione per FreeBasic è gratuita, ma ne esistono altre a pagamento (per esempio quella relativa a RealBasic). Il link che ho indicato è (guarda caso) quello della versione libera per FreeBasic. Nel file di download sono presenti anche alcuni esempi, che aiutano a prendere pratica del programma. Comunque, se si ha una certa esperienza di ambienti di sviluppo “visuali”, il tempo di apprendimento è piuttosto basso. Consiglio caldamente questo “partner” di FreeBasic ; l’abbinamento dà luogo ad un formidabile sistema di sviluppo per programmare sotto Windows e …cosa meravigliosa in questi momenti bui… è tutto gratis. Purtroppo il grande pregio di FreeBasic, quello di esistere anche in ambiente Linux, non viene rafforzato da FireFly_FB, dato che quest’ultimo esiste solo su piattaforma Windows, ma penso che ci si possa accontentare 🙂 Esiste un IDE per FreeBasic anche sotto Linux (Glade?), ma al momento non l’ho ancora utilizzato e quindi non sono la persona giusta per dare consigli ! Spero che la mia risposta sia stata utile…

una schermata relativa ad uno dei programmi di esempio

una schermata relativa ad uno dei programmi di esempio (cliccare l’immagine per ingrandire)

Simple trick to add zip file to jpg image

Sometimes I have a PCB (printed circuit board) to realize. Usually, I send my design to local (italian) producers, but recently I’ve seen on a famous internet shop (four letters, starting with ‘e’ ending with ‘y’) some advertise from chinese producers, giving the PCB service at VERY low price. My PCB design files are always in GERBER format, with all sections shrinked in a single zip file.

If you decide to send your design to such chinese producers, generally you must mail your zipped gerber to the factory using your private email, ‘cause the “famous internet shop” only accepts jpg files as attachments in messages from buyer to seller (or viceversa).

This limit gaves me an idea : to create a jpg file that has a image part (my logo, for example) and hidden embedded gerber file. This way, I can send the data using the mail messaging offered by “the famous internet shop” without the need to use my private email account.

The procedure to create such embedded jpg is VERY simple:

a) put the gerber.zip (or ANY OTHER zip file) and the “container” image.jpg on a temp folder…

b) open a “dos command” window, navigate to the temp folder, then type: copy /b image.jpg + gerber.zip miximage.jpg (I usually create a batch file with this command in that folder,)

This command creates a copy (binary copy, thanks to the /b option) of the jpg PLUS the zip file. Now, if you open the resultant miximage.jpg with an image viewer, you will see the “container” image, but if you right click on the same jpg file, choosing “open with”, and selecting the application 7zFM.exe (from folder 7-Zip, under program files), you will discover that all your zip file contents are also present. The link to 7Z, my favourite zip/unzip application, is on the right side of this page, under useful links.

With this “mixed” file, you can use the mail message system of the “famous internet shop” to send your data to the chinese factory, attaching to your message the embedded jpg file. This is good for avoiding to use your private email and for have a seller-buyer transaction covered by the payment protections of the shop.

Hope this will be useful for someone…

Html più Php = labirinto interattivo

Ho realizzato, qualche tempo fa per scopi didattici, usando unicamente html e php, un piccolo “labirinto” interattivo che può essere facilmente installato su qualsiasi host (io uso, ovviamente, Altervista) che permetta di far “girare” programmi PHP. Per disegnare le “stanze” con le varie combinazioni di porte e oggetti, ho usato un software 3D dell’Ikea:si chiamava Kitchen Planner, era una versione “free” del 2005, se non sbaglio. Una volta disegnate le varie stanze, ne ho fatto dei files jpg che vengono richiamati a seconda della “mappa” del labirinto, inserita in un file di testo, e della “porta” scelta dall’utente durante l’esplorazione dello “strano edificio”. In qualche stanza ci sono “oggetti” cliccabili, ma non voglio dirvi tutto… Se volete dargli un’occhiata cliccate su questo link e vi troverete sulla pagina di partenza, che vedete qui sotto…

labishot

FreeBASIC – Esercizi

Steganografia
Vi propongo un altro esercizio per il FreeBASIC. Si tratta di un programmino scritto da me che consente di leggere un messaggio “nascosto” in una immagine. Il file immagine che contiene il messaggio è questo qui sotto:

foto con messaggio nascosto :)

Si tratta, come vedete, di una immagine in formato BMP con 256 toni di grigio. L’utilizzo di questo formato è dettato dalla semplicità di decodifica di tale tipo di file. Invito chiunque fosse interessato (basta fare una ricerca su Google) a studiare cosa c’è scritto nell’intestazione (lo header) di un file .BMP ; non è per niente complicato.
Bene: come possiamo “nascondere” un testo in una fotografia ? Semplice… ogni pixel di una foto in formato BMP a 256 toni di grigi è un byte che può avere un valore da 0 a 255 ; lo zero rappresenta il nero totale, il 255 invece è il bianco pieno. Tutti i valori intermedi sono i vari livelli di grigio. Allora noi che facciamo ? prendiamo il bit meno significativo di ognuno di questi bytes e lo modifichiamo per comporre una sfilza di bits che saranno il nostro messaggio testuale “nascosto”. Cambiare il colore di un pixel da 255 a 254, per esempio, risulterà totalmente invisibile all’occhio umano, perché si passerà da un bianco pieno a un bianco appena un po’ meno pieno. Lo stesso dicasi di un pixel che aveva valore 000 (tutto nero) e passa a 001 (appena un po’ meno nero). L’occhio non percepisce queste piccole differenze, specie perché è attirato dalla visione “globale” della fotografia.
Vi propongo il listato del programma sorgente in FreeBASIC che esegue il lavoro di decodifica. Appena lo avrete compilato, mandatelo in esecuzione e vi troverete un nuovo file di testo, chiamato epgficara.txt, contenente un mio breve curriculum vitae. Nota importante: mettete nella stessa cartella il programma che compilerete e il file immagine epgficara.bmp che potrete scaricare da questa pagina cliccando con il tasto destro e facendo “salva con nome” e assicuratevi che la cartella in cui mettete le cose sia provvista dei diritti di scrittura, altrimenti il programma non potrà produrre il file di testo in uscita.
Ecco, quindi, il file sorgente per FreeBASIC:

dim shared as string nfi, a
dim shared as long start, leng, fl
dim shared as ubyte db, src

print "Decodifica steganografia in file BMP - 256 livelli grigio - V13.0316 - (c)2013 Emilio P.G. Ficara"
nfi = "epgficara.bmp" ' nome del file da decodificare
If Dir(nfi) = "" then
  Print "Errore: il file ";nfi;" non esiste"
  Goto exits
EndIf

Open nfi for binary as #1 ' apri il file da leggere
a = Input$(54,#1) ' leggi solo l'intestazione (header)
If Left(a, 2) <> (Chr(&h42) + Chr(&h4d)) then ' se errato il "magic number"
  Print "Errore: non è un file BMP"
  Goto exits
EndIf
If Mid(a,&h1C+1,2) <> (Chr(8)+Chr(0)) then ' se non è 8 bit per pixel
  Print "Errore: non è 8 bit per pixel"
  Goto exits
EndIf
If Mid(a,&H1E+1,4) <> (Chr(00)+Chr(00)+Chr(00)+Chr(00)) then ' se è compresso
  Print "Errore: è compresso RLE-8 o RLE-4"
  Goto exits
EndIf
If Mid$(a,&H2E+1,4) <> (Chr(00)+Chr(01)+Chr(00)+Chr(00)) then ' se non è 256 toni di grigio
  Print "Errore: non è 256 toni di grigio"
  Goto exits
EndIf

start = Asc(Mid(a,&H0a+1,1)) ' calcola l'indirizzo di inizio del primo pixel d'immagine
start = start + Asc(Mid(a,&H0b+1,1))*&H100
start = start + Asc(Mid(a,&H0c+1,1))*&H10000
start = start + Asc(Mid(a,&H0d+1,1))*&H1000000

leng = Asc(Mid(a,&H22+1,1)) ' calcola lunghezza in bytes dell'immagine
leng = leng + Asc(Mid(a,&H23+1,1))*&H100
leng = leng + Asc(Mid(a,&H24+1,1))*&H10000
leng = leng + Asc(Mid(a,&H25+1,1))*&H1000000

Open "epgficara.txt" for output as #9 ' apri file di uscita (testo)

fl = 54 ' salta la tabella dei colori
While fl < start
  get #1,,src ' leggi un pixel (un byte) del file BMP
  fl = fl+1
Wend

fl = 0 ' contatore dei bytes in input
db = 0 ' byte ricomposto dai singoli bits (inizialmente a 0)
While fl < leng
  If (fl > 0) And ((fl and 7) = 0) then ' per 8 bytes di immagine (excludendo il primo)
    Print #9, Chr(db); ' scrivi un carattere sul file di output (testo)
    db = 0 ' azzera il byte per la ricomposizione dei bits
  EndIf

  get #1,,src ' leggi un pixel (un byte) dal file BMP
  If (src and &H01) then ' se il nostro bit nascosto è 1
    db = db Or (2 ^ (fl and 7)) ' metti a 1 il relativo bit nel byte ricomposto
  EndIf
  If db = &Hff then exit while ' se trovo la combinazione &HFF (8 volte 1), il testo è finito
  fl = fl + 1 ' altrimenti incremento il numero di bytes letti
Wend

exits:
close ' chiudi tutti i files aperti
End

P.S. se qualcuno preferisse avere il programma già compilato e pronto per essere eseguito, potrà scaricare il file stegodec.zip , decomprimerlo in una qualsiasi cartella, aggiungere -come detto prima- il file BMP da decrittare e lanciare l’eseguibile. Non è richiesta alcuna installazione, non viene modificata nessuna voce di registro.

FreeBASIC – esercizi

Permutazioni semplici e soluzione esercizio Bocconi

Eccomi di nuovo a voi con un programmino in FreeBASIC. L’occasione per scriverlo è capitata ieri, quando mi è stato presentato un problema di “allenamento” per le gare internazionali di matematica organizzate dall’università Bocconi. Questi “allenamenti” sono basati su esercizi dati in passato per altre gare dello stesso tipo; in particolare, questo che vi propongo si trovava in una gara del 2006. Potete prelevare il file PDF da questo link che ho trovato su internet. Nel documento PDF ci sono diversi esercizi, ma quello che mi è stato proposto è il numero 10, denominato CONNESSIONE. Devo dire che la parte più difficile della soluzione è stata quella di interpretrare la traccia che, francamente, era parecchio oscura e talvolta rasentava la mancanza di senso, come nella frase “la somma, magari costituita da un unico addendo”, ma una volta capito quello che veniva inteso, il resto è stato facile.
Con un po’ di ragionamenti (partendo dalle somme 1 e 2) si trova facilmente la soluzione, anzi una delle soluzioni possibili. E questo basta per dire di aver risolto il problema. Ok. Dopo un po’ ho pensato di realizzare un programma che trovasse, matematicamente, tutte le possibili soluzioni. Ho impostato la traccia in un modo diverso, che a me è sembrato più chiaro. Ho immaginato sette villette disposte in un certo territorio. Ogni villetta ha il proprio numero civico, da 1 a 7. Da ogni villetta si scorgono una o più delle altre (alcune non sono reciprocamente visibili) e le persone che vivono in ognuna di esse, decidono di calcolare la somma dei numeri civici delle villette che riescono a vedere. I risultati di 6 di questi personaggi sono noti (1, 2, 3, 5, 8, 13), si chiede quale sia la somma calcolata dal settimo. Ho realizzato uno schemino per spiegare queste relazioni:

casette

Sa = B
Sb = A + C + F
Sc = B + D
Sd = C + E + F + G
Se = D
Sf = B + D + G
Sg = D + F

Per ‘Sa’ si intende la somma dei numeri civici delle villette viste dall’abitazione [ a ], per ‘Sb’ quelli visti dalla villetta [ b ] e così via. In pratica le linee che collegano le casette indicano la possibilità di “vedere” le altre. Il programma, quindi, agisce così: genera tutte le possibili PERMUTAZIONI SEMPLICI di 7 elementi, calcola le equazioni per ognuna delle permutazioni e verifica nei risultati se 6 di essi corrispondono a quelli dati nella traccia ; in quel caso, rivela il settimo che è la soluzione. Le permutazioni di 7 elementi sono 5040 (corrispondenti a 7 fattoriale), ma le soluzioni sono solo 8, delle quali 4 non valide perché alcune delle somme si ripetono. Le restanti 4 danno come totale 22, 21 o 19 (quest’ultimo in due permutazioni), che sono quelle indicate come risultato dalla Bocconi.
Le permutazioni vengono tutte salvate sul file di uscita risultati.txt e dopo ogni riga valida, cioè che risponde ai requisiti, viene stampato un ‘*** Ok’ seguito dalle somma calcolate da tutti gli “abitanti” delle villette, da ‘Sa’ a ‘Sg’. Di sotto, il listato del programma :

Dim Shared As Integer contatore(7) ' array usato come contatore a 7 digit
Dim Shared As Integer civici(7) ' array dei numeri civici
Dim Shared As Integer somme(6) ' array delle somme gia' note
Dim Shared As Integer nrow ' numero riga per stampa
Dim Shared As Integer finito ' segnalatore di iterazioni finite

' subroutine per creazione nuova permutazione semplice
'-----------------------------------------------------
Sub Newrow()
Dim As Integer x,y

retry:
    x = 7 ' posiziona su elemento piu' a destra del contatore
    Do
        contatore(x) = contatore(x) +1 ' passa a nuovo digit
        If contatore(x) <= 7 Then Exit Do ' termina se non li hai usati tutti
        contatore(x) = 1 ' altrimenti ricomincia dal primo digit
        x = x -1 ' passa al digit immediatamente a sinistra
    Loop Until x = 0 ' esegui per tutti i digits
    If x = 0 Then ' se il conteggio è finito (tutti i digits usati)
        finito = 1 ' attiva segnale di conteggio terminato
        Exit Sub ' termina la subroutine
    Endif 

    ' vogliamo le permutazioni semplici, quindi saltiamo
    '  le combinazioni con elementi ripetuti
    For x = 1 to 6
        For y = x+1 to 7
            If contatore(x) = contatore(y) Then Goto retry
        Next y
    Next x
End Sub

' subroutine per la stampa della attuale permutazione
'----------------------------------------------------
Sub Outrow()
Dim As Integer x

    Print #1,nrow, ' scrivi nuova riga permutazione semplice
    nrow = nrow +1
    For x = 1 to 7
        Print #1, civici(contatore(x));" ";
    Next x
    Print #1, ' fine linea

End Sub

' subroutine per il calcolo del problema
'---------------------------------------
Sub Calcola()
Dim As Integer S(7)
Dim As Integer x, y, num

    ' calcolo somme numeri civici visibili da ogni villetta
    S(1) = civici(contatore(2)) ' Sa = b
    S(2) = civici(contatore(1)) + civici(contatore(3)) + civici(contatore(6)) ' Sb = a+c+f
    S(3) = civici(contatore(2)) + civici(contatore(4)) ' Sc = b+d
    S(4) = civici(contatore(3)) + civici(contatore(5)) + civici(contatore(6)) + civici(contatore(7)) ' Sd = c+e+f+g
    S(5) = civici(contatore(4)) ' Se = d
    S(6) = civici(contatore(2)) + civici(contatore(4)) + civici(contatore(7)) ' Sf = b+d+g
    S(7) = civici(contatore(4)) + civici(contatore(6)) ' Sg = d+f

    num = 0 ' azzera numero di somme valide
    For x = 1 to 7 ' per tutte le somme calcolate
        For y = 1 to 6 ' per tutte le somme gia' note
            If S(x) = somme(y) then
                num = num +1
                y = 6 ' termina il for interno
            Endif
        Next y
    Next x
    If num = 6 Then ' tutti le somme valide
        Print #1,"*** ok ";
        For x = 1 to 7
            Print #1, "[";S(x);"] ";
        Next x
        Print #1,
    Endif
End Sub

' programma principale
'---------------------

    Print " **********************************************************"
    Print " ** Programma per il calcolo della soluzione al problema **"
    Print " **  delle sette casette con numeri civici da 1 a 7, che **"
    Print " **  si vedono nella mappa allegata al problema.         **"
    Print " ** Compilato con FreeBasic, opzione QB - E.Ficara 2011  **"
    Print " **********************************************************"

    civici(1) = 1: civici(2) = 2: civici(3) = 3: civici(4) = 4 ' assegna numeri civici alle casette
    civici(5) = 5: civici(6) = 6: civici(7) = 7

    somme(1) = 1: somme(2) = 2: somme(3) = 3 ' assegna le somme gia' note
    somme(4) = 5: somme(5) = 8: somme(6) = 13

    For i = 1 to 6 ' inizializza contatore 7 digit
        contatore(i) = 1
    Next i
    contatore(i) = 0 ' combinazione -1 (per successivo incremento con Newrow)

    nrow = 1 ' inizializza numero linea per stampa
    finito = 0 ' inizializza il segnalatore di iterazioni complete

    Open "risultati.txt" For Output As #1 ' prepara file di uscita
    Print #1,"Permutazioni semplici:" & Chr$(13) & Chr$(10)
    Do ' inizia loop combinazioni
        Newrow ' calcola nuova permutazione semplice
        If finito > 0 then Exit Do ' esci se segnale di conteggio finito 
        Outrow ' altrimenti stampa linea
        Calcola ' esegui calcolo del problema
    Loop
    Close #1

    Print "Programma terminato. E' stato creato il file risultati.txt"
    Print "Premere un tasto qualsiasi per terminare..."
    Do
        If Inkey$ <> "" then Exit Do
    Loop
End

FreeBASIC – esercizi

Senti, ma… come lo facevano i Babilonesi ?

Sebbene il titolo possa dar adito a sospetti sull’argomento trattato, quello che vi propongo è solo un altro piccolo esempio di utilizzo del FreeBASIC. Mi sono trovato a dover fare dei calcoli con le radici quadrate in un progetto su un microcontrollore. I microcontrollori NON hanno la possibilità di eseguire calcoli di questo tipo, diciamo che in genere possono fare (in modo primitivo, cioè senza scrivere un programma apposito) addizioni, sottrazioni, moltiplicazioni e divisioni per multipli di 2 (istruzioni di shift a sinistra e a destra), ma non è questo l’argomento che ci interessa.

Insomma, trovandomi a dover fare una radice quadrata senza avere una istruzione adeguata (intendo istruzione del microcontrollore, non la mia !!!) , mi sono ricordato di un metodo con iterazioni successive che si dice sia stato inventato dai Babilonesi. Ora io, con quattromila anni di ritardo, l’ho provato con un programmino facile-facile in FreeBasic, prima di trasportare lo stesso algoritmo sul microcontrollore. Ovviamente, questo listato che vi propongo può lavorare anche con numeri con la virgola, mentre quello che adotterò sul microcontrollore potrà lavorare solo su numeri interi. Ecco il listato:

' programma principale
'---------------------

    Print " **********************************************************"
    Print " ** Programma per il calcolo della radice quadrata di un **"
    Print " **  numero con il metodo BABILONESE.                    **"
    Print " ** Compilato con FreeBasic, opzione QB - E.Ficara 2011  **"
    Print " **********************************************************"
    Do
        Print: Print "Nota: i numeri decimali vanno inseriti con il punto, non la virgola.": print
        Input "Numero di cui si vuol calcolare la radice quadrata (0 per finire) "; num
        If num < 0 Then
            Print "La radice quadrata di un numero negativo ? Non la so fare... e tu ?"
            Print " - dai, ti cambio il segno..."
            num = -num ' ecco fatto
        Endif
        If num = 0 Then Exit Do ' termina se l'utente ha inserito 0 
        prec = 0.01 ' precisione 0.01 (due cifre decimali); modificare se serve
        sq = 1 ' inizializza risultato con numero arbitrario
        old = num ' metti al massimo possibile il valore iterazione precedente 
        Do ' loop iterazioni
            sq = (sq + num / sq) / 2 ' calcola nuova iterazione
            If (old-sq) < prec Then Exit Do ' se la precisione è raggiunta, termina loop
            old = sq ' altrimenti aggiorna valore precedente
            Print "... iterazione: "; sq
        Loop
        Print "risultato: ";sq
    Loop
End

FreeBASIC – esercizi

Voglio proporvi uno strumento utile per lo sviluppo di semplici programmi in ambito matematico e non solo. Si tratta del FreeBASIC, un compilatore Basic gratuito ed open-source che funziona molto bene ed ha il grosso pregio di poter compilare anche i vecchi listati di QBasic e GW Basic che erano (un tempo) usatissimi e con i quali sono state sviluppate migliaia di applicazioni, matematiche, scientifiche e anche ludiche (i primi videogames). Io l’ho installato sul mio portatile con Win7 Home Edition e funziona a meraviglia, ma esiste anche in ambiente LINUX ed ha esattamente le stesse caratteristiche. Nella colonna a destra, sotto ‘links utili’, trovate il collegamento al sito per il download.

Calcolo numeri primi

Un paio d’anni fa mi fu proposto di risolvere un problema scolastico nel quale si chiedeva l’elenco dei numeri primi (fino a 2000) che avessero queste caratteristiche:
a) avere differenza 10 col numero primo che lo precedeva
b) avere tutte le cifre diverse

Risolsi il problema scrivendo un piccolo programmino con il GFW-Basic (un vecchio compilatore a 16 bit per Windows, molto efficiente) ed ora, con minime modifiche, l’ho ricompilato con FreeBASIC e l’ho fatto girare su Win7 (in una finestra DOS) ; funziona perfettamente. Ve lo propongo in forma di listato in modo che possiate provare a compilarlo voi stessi, una volta installato il FreeBASIC. Aggiungo il contenuto del file compila.bat che uso per creare l’eseguibile:

C:\FreeBASIC\fbc.exe -lang qb primi.bas
pause

Naturalmente, questo prevede che il FreeBASIC sia stato installato nella directory C:\FreeBASIC e che al listato abbiate dato il nome primi.bas. Se il compilatore è stato installato in una diversa directory o il nome del file sorgente è diverso, modificate il batch di conseguenza.

Ecco il listato del file sorgente primi.bas :

Dim primi(2000) ' buffer per numeri primi
Dim diff(2000) ' buffer per differenze

    Print " *********************************************************"
    Print " ** Programma per il calcolo dei numeri primi e delle   **"
    Print " **  differenze tra un numero primo e il precedente.    **"
    Print " ** Compilato con FreeBasic, opzione QB - E.Ficara 2011 **"
    Print " *********************************************************"

    primi(1) = 2 ' il primo numero primo (escludendo 1)
    diff(1) = 1 ' la prima differenza
    last = 2 ' indice iniziale dell'ultimo numero primo calcolato
    For i = 2 To 2000 ' limita la ricerca al numero 2000; modificare se serve
        For j = 1 To last - 1 ' prova divisibilita' con numeri precedenti
            If (i / primi(j)) = Int(i / primi(j)) Then Exit For ' esci se divisione intera
        Next j
        If j = last Then ' se non ha trovato divisori (e' un numero primo)
            ' NOTA: le prossime istruzioni servono per ESCLUDERE dalla lista dei numeri primi
            '       quelli che contengono cifre uguali (11 per esempio)
            m = 1110 ' inizializza valore migliaia (arbitrario) <> centinaia e decine
            c = 100 ' inizializza valore centinaia (arbitrario)
            d = 110 ' inizializza valore decine (arbitrario) <> centinaia
            u = i ' inizializza unita' con il numero in esame 
            If u >= 1000 Then ' se maggiore o uguale a 1000
                m = Int(u / 1000) ' m contiene le migliaia
                u = u - m * 1000 ' u contiene il resto (0-999)
            EndIf
            If u >= 100 Then ' se maggiore o uguale a 100
                c = Int(u / 100) ' c contiene le centinaia
                u = u - c * 100 ' u contiene il resto (0-99)
            EndIf
            If u >= 10 Then ' se maggiore o uguale a 10
                d = Int(u / 10) ' d contiene le decine
                u = u - d * 10 ' u contiene il resto (0-9)
            EndIf
            ' per mettere in lista tutti i numeri primi, sostituire la prossima linea
            ' con    If (1) Then    o eliminarla insieme al suo EndIf
            If m <> c And m <> d And m <> u And c <> d And c <> u And d <> u Then ' se m,c,d e u sono diversi
                primi(last) = i ' salva il numero in esame tra i primi
                diff(last) = i - primi(last - 1) ' calcola e salva la differenza col precedente
                last = last + 1 ' incrementa indice dell'ultimo numero calcolato
            EndIf
        EndIf
    Next i

    Open "primi.txt" For Output As #1 ' prepara file di uscita
    Print #1," 1", " 0" ' scrivi il primo numero primo :-)
    For i = 1 To last - 1 ' scrivi tabella numeri primi e differenze
        Print #1,primi(i), diff(i)
    Next i

    Print #1, ' interlinea

    ' scrivi tabella dei numeri primi che hanno differenza 10 col precedente
    For i = 1 To last - 1
        If diff(i) = 10 then
            Print #1,primi(i), diff(i), primi(i - 1)
        EndIf
    Next i
    Close #1

    Print "Programma terminato. E' stato creato il file primi.txt"
    Print "Premere un tasto qualsiasi per terminare..."
    Do
        if Inkey$ <> "" then Exit Do
    Loop

Il programma genera un file di uscita chiamato primi.txt nel quale sono elencati i numeri primi (eccetto quelli che hanno cifre uguali, tipo l’ 11 per intenderci) e, dopo questi, la lista dei numeri primi che hanno differenza 10 con il precedente (nel limite di 2000 posto come massimo per l’indagine).

Modificare le Env_Variables senza ri-flashare tutto

Ho ricevuto una domanda tramite la form per l’invio dei files:
“… Dopo modifiche software e hardware mi è venuto un dubbio che ho appena postato:
How can I update env_boot without flashing all the system?

As of is so difficult to find the correct number for our tablet we have to try many time…but is really necessary to flash completely your tablet or is possible to change only env_boot?
I don’t know…for example with an empty wmt_scriptcmd (?)

Thanks
Marco

Tu hai idea se sia possibile? …”
Rispondo a Marco: le “environment variables” possono essere modificate agendo con un apposito comando del programma U-Boot ; naturalmente per poter usare il programma, bisogna collegare un terminale seriale. Raccomando la lettura di questo articolo per “entrare in argomento”. Aggiungo che il file wmt_scriptcmd può effettuare le stesse operazioni, cioè è possibile crearne uno in cui si settano solo le env_variables e non si fa niente altro. Il programma U-Boot, infatti, come prima operazione va a vedere se c’è una MMC (la microSD) inserita nello slot, poi – se c’è – verifica se all’interno è contenuto il file wmt_scriptcmd ed eventualmente esegue le varie istruzioni programmate. E’ da notare che il file wmt_scriptcmd NON è un semplice file di testo, perché contiene all’inizio uno speciale “header” con un codice CRC per verificare che sia compilato correttamente e sia in grado di lavorare sul sistema su cui lo si sta lanciando. Partendo da un file di testo, si può utilizzare il programma mkimage.exe per ottenere il file idoneo ad essere eseguito sulla microSD.

Modificare le env_variables da terminale seriale.
Una volta entrati in connessione con il programma U-Boot, per cambiare una env_variable basta dare il comando setenv ; per esempio, se vogliamo cambiare il tempo di bootdelay, basterà scrivere setenv bootdelay 3 (da notare che in tutti i comandi setenv NON deve essere scritto il segno “=”, anche se si sarebbe indotti a farlo perché il comando printenv lo mostra a fianco della variabile ; esempio: bootdelay = 3). Con questo comando diciamo al sistema che il ritardo al boot (quello che ci permette di fermare l’autostart) sarà di 3 secondi. Per salvare questa variabile in modo permanente, basterà dare il comando saveenv ; per verificare le modifiche e per avere la lista di tutte le variabili memorizzate sulla memoria SPI flash (sì, è lì che vengono memorizzate) si potrà dare il comando printenv.

Così come per la variabile bootdelay, qualsiasi altra variabile può essere modificata nello stesso modo ; resettando il tablet, il successivo boot avverrà con i nuovi valori delle variabili salvate. Attenzione: se si scrivono valori “a casaccio” oppure semplicemente errati, si corre il rischio di rendere il tablet “un mattone” (a brick) e perciò è imperativo conoscere ciò che si fa, prima di operare ! Esiste anche un modo per eliminare una delle env_variables : basta scrivere il comando setenv e il nome della variabile, senza assegnare alcun valore. La variabile sarà eliminata. Naturalmente, anche questo comando va usato con ESTREMA cura 🙂

Le gioie di Javascript #2

Passiamo a due nuovi concetti, molto importanti : uno per il linguaggio Javascript e precisamente l’ array, e uno per il tag div dell’html e precisamente la proprietà z-index. Prima di iniziare a parlarne, vediamo una piccola “demo” di come questi due concetti possano essere applicati. Cliccando su questo link si aprirà una pagina del browser con quattro “fantasmini” che si muovono sullo schermo…

Di seguito, il listato del programma Javascript (demo2.js) :

//<!-- javascript demo #2 - Emilio Ficara 2012
var i,id,timer; // definizione variabili per indice oggetti,identificatore oggetti,timer
var xpos,ypos,xstep,ystep,xsize,ysize; // definizione variabili posizione, spostamento, dimensioni

  xpos = new Array(); // crea un array di posizioni X per i vari oggetti
  ypos = new Array(); // crea array per posizioni Y
  xstep = new Array(); // crea array per passo spostamenti X
  ystep = new Array(); // crea array per passo spostamenti Y
  xsize = new Array(); // crea array dimensione X oggetti
  ysize = new Array(); // crea array dimensione Y oggetti

  xpos[0] = 0; xpos[1] = 160; xpos[2] = 320; xpos[3] = 480; // posizione X iniziale per 4 oggetti  
  ypos[0] = 0; ypos[1] = 120; ypos[2] = 240; ypos[3] = 360; // posizione Y iniziale
  xstep[0] = 3; xstep[1] = 3; xstep[2] = 3; xstep[3] = 2; // passo spostamenti X
  ystep[0] = 2; ystep[1] = 2; ystep[2] = 2; ystep[3] = 3; // passo spostamenti Y
  xsize[0] = 64; xsize[1] = 48; xsize[2] = 80; xsize[3] = 128; // dimensioni X
  ysize[0] = 64; ysize[1] = 48; ysize[2] = 80; ysize[3] = 128; // dimensioni Y

  NewStep(); // esegui la funzione per la prima volta (dopo verrà richiamata da timer)

function NewStep() // nuovo step spostamento oggetto mobile
{
  for(i = 0; i < 4; ++i) // fai andare la variabile i da 0 a 3 con incremento di 1
    {
    xpos[i] += xstep[i]; // nuova posizione X oggetto [i] di array
    ypos[i] += ystep[i]; // nuova posizione Y oggetto [i] di array
    if(xpos[i] > (document.body.clientWidth -xsize[i]) || xpos[i] < 0) // se oggetto [i] oltre il bordo destro o sinistro
      {
      xstep[i] = -xstep[i]; // inverti lo step di spostamento orizzontale per l'oggetto [i]
      xpos[i] = xpos[i] +xstep[i] +xstep[i]; // esegui lo spostamento due volte (era andato già oltre)
      }
    if(ypos[i] > (document.body.clientHeight -ysize[i]) || ypos[i] < 0) // se oggetto [i] oltre il bordo superiore o inferiore
      {
      ystep[i] = -ystep[i]; // inverti lo step di spostamento verticale per l'oggetto [i]
      ypos[i] = ypos[i] +ystep[i] +ystep[i]; // esegui lo spostamento due volte (era andato già oltre)
      }
    id = "L"+i; // assegna identificativo L0..L3 per l'oggetto che vogliamo muovere
    document.getElementById(id).style.top=ypos[i]+"px"; // assegna la nuova posizione verticale all'oggetto [i]
    document.getElementById(id).style.left=xpos[i]+"px"; // assegna la nuova posizione orizzontale all'oggetto [i]
    }
  timer = setTimeout("NewStep()",20); // attiva timer per eseguire di nuovo la funzione NewStep tra 20 mS
}
//->

e della pagina html usata come “contenitore” (demo2.htm) :

<html><head><title>Javascript demo #2 - Emilio P.G. Ficara 2012</title></head>
<body bgcolor="#FFFFFF">
<div id="L0" style="position:absolute; z-index:1">
 <img src="img/sprite0.png">
</div>
<div id="L1" style="position:absolute; z-index:2">
 <img src="img/sprite1.png">
</div>
<div id="L2" style="position:absolute; z-index:3">
 <img src="img/sprite2.png">
</div>
<div id="L3" style="position:absolute; z-index:4">
 <img src="img/sprite3.png">
</div>
<script src="demo2.js"></script>
</body></html>

Possiamo notare, nel listato demo2.htm, la presenza di 4 tag div, ognuno dei quali ha un proprio identificativo ( id=”L0″ .. id=”L3″ ) e la proprietà z-index di valore diverso; in questo “giochetto” i diversi valori di z-index determinano quale oggetto è “in primo piano”, quale in “secondo piano”, eccetera. Lo z-index può essere considerato come un foglio trasparente su cui appiccichiamo un adesivo che è il nostro oggetto. Facciamo un esempio : i quattro “fantasmini” che vediamo nel gioco hanno ognuno un numero disegnato sopra, da 1 a 4, che corrisponde al valore di z-index che è stato assegnato al tag div che li contiene. Ho usato questi numeri per rendere più chiare le cose. Se ci fate caso, quando i fantasmini si “incrociano”, qualcuno rimane visibile, mentre un altro viene “nascosto dietro”. Questa è la funzione z-index. L’oggetto che ha z-index = 4 (il fantasmino arancione) è sempre visibile, cioè, in caso di “incroci”, copre sia il fantasmino 1, sia il 2, sia il 3. A sua volta, il fantasmino 3 rimane visibile se incrocia il 2 o l’1. Insomma, è come se avessimo i nostri quattro fogli trasparenti sovrapposti, ognuno con il suo adesivo appiccicato sopra, e muovessimo i singoli fogli : se chiamiamo “z-index = 4” il foglio in cima agli altri, è chiaro che tutto quello che c’è sotto l’adesivo non sarà visibile, perché “nascosto dietro”. Lo stesso vale per tutti gli altri livelli, foglio per foglio. Con questo principio è possibile creare animazioni in cui è presente una “profondità” dei livelli, esattamente come se stessimo lavorando con diversi fogli trasparenti sovrapposti.

Per quanto riguarda Javascript, invece, abbiamo fatto uso di arrays . Se consideriamo una variabile come una “scatola” in cui mettere delle cose, allora un array è una cassettiera, con un certo numero di cassetti, così possiamo dire “prendi le camicie che ci sono nel terzo cassetto” e dare un’indicazione esatta di dove si trova ciò che ci serve. Nella demo #1 muovevamo, sul nostro quadrato di gioco, un solo oggetto: la palla, e così avevamo una sola variabile per ognuno dei parametri che ci interessavano : xpos per la posizione orizzontale, ypos per quella verticale eccetera. Ora, nella demo #2, muoviamo 4 oggetti diversi, perciò abbiamo bisogno, per ognuno di essi, delle stesse informazioni. Allora, invece di usare una singola variabile, abbiamo usato degli arrays. Così xpos non è più una singola variabile, ma una “cassettiera” in cui possiamo andare a prendere, basandoci su un indice (la posizione del cassetto) i dati necessari per un determinato oggetto. L’uso di questa tecnica ci permette di scrivere le istruzioni per muovere tutti e quattro gli oggetti in un singolo ciclo FOR ; il ciclo FOR è scritto in modo da far andare una variabile (usata come indice, ovvero il numero del “cassetto”) da 0 a 3 compresi, così da svolgere ogni volta, al suo interno, le operazioni relative agli oggetti [0], [1], [2] e [3]. Con la stessa tecnica è possibile aumentare a piacere il numero di oggetti trattati, semplicemente “allungando” gli arrays. Si noti che gli arrays possono avere più dimensioni, in quel caso, però, è meglio far riferimento a matrici. Ne parleremo in una fase successiva.