lunedì 14 gennaio 2019

Addipresto Lanza

Era da tempo che volevo aggiungere alla mia collezione di regoli calcoatori una calcolatrice analogica per addizioni ma i prezzi su Ebay non sono trascurabili. Ieri ad un mercatino per 10 euro ho preso questa Addipresto Lanza completa del suo stilo originale perfettamente funzionante (a dire il vero sono strumenti cosi' semplici che e' difficile si rompano)




E' databile indicativamente seconda meta' degli anni 60 ed ha 7 rotori decimali. Non ha indicatore di overflow ma semplicemente il conteggio riparte da zero


Per effettuare una somma, per esempio 65+47 (come nel video sottostante). si procede puntando lo stilo sul numero delle unita' e ruotando verso il basso procedendo poi con il rotore delle decine. Inserito il primo addendo si ripete la procedura per il secondo per avere infine il risultato sul display in alto ovvero 112. Il reset e' effettuato con la levetta rossa



Le sottrazioni possono essere effettuate con i numeri in rosso come complemento a 9

Alcune informazioni sul meccanismo interno si possono ricavare a questo link

mercoledì 9 gennaio 2019

Cordova File Plugin per salvare file

questo esempio e' stato ripreso da questo esempio

si parte da zero

cordova create MyApp
cordova platform add android
cordova plugin add cordova-plugin-file

a questo punto e' stato creato il progetto base. Si apre Android Studio e si risolvono i vari errori di Gradle e poi si fa una prima build. In seguito si modificano i file come segue

Nella pagina html l'unico aspetto importante e' che siano importati cordova.js e /js/index.js

/assets/www/index.html
////////////////////////////////////////////////////////////
<html>
    <head>

        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Hello World</title>
    </head>
    <body onload="onLoad()">
        <div class="app">
            <h1>Apache Cordova</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
            </div>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>

    </body>
</html>
////////////////////////////////////////////////////////////

sull'evento deviceready si aggiunge quindi il codice evidenziato

/assets/www/js/index.js
///////////////////////////////////////////////////////////

var app = {
    // Application Constructor
    initialize: function() {
        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
    },

    // deviceready Event Handler
    //
    // Bind any cordova events here. Common events are:
    // 'pause', 'resume', etc.
    onDeviceReady: function() {
        this.receivedEvent('deviceready');
    },

    // Update DOM on a Received Event
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
        var fileName = 'myfile.txt';    // your file name
        var data = '...';               // your data, could be useful JSON.stringify to convert an object to JSON string
        window.resolveLocalFileSystemURL( cordova.file.externalRootDirectory, function( directoryEntry ) {
            directoryEntry.getFile(fileName, { create: true }, function( fileEntry ) {
                fileEntry.createWriter( function( fileWriter ) {
                    fileWriter.onwriteend = function( result ) {
                        console.log( 'pippoplutopaperino' );
                    };
                    fileWriter.onerror = function( error ) {
                        console.log( error );
                    };
                    fileWriter.write( data );
                }, function( error ) { console.log( error ); } );
            }, function( error ) { console.log( error ); } );
        }, function( error ) { console.log( error ); } );
    }
};

app.initialize();

///////////////////////////////////////////////////////////

/res/config.xml
anche in questo file si modifica aggiungendo la parte evidenziata
///////////////////////////////////////////////////////////
<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <feature name="Whitelist">
        <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" />
        <param name="onload" value="true" />
    </feature>
    <name>HelloCordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <allow-intent href="market:*" />
    <preference name="loglevel" value="DEBUG" />
    <feature name="File">
        <param name="android-package" value="org.apache.cordova.file.FileUtils" />
        <param name="onload" value="true" />
    </feature>
    <allow-navigation href="cdvfile:*" />
    <preference name="AndroidPersistentFileLocation" value="Compatibility" />
    <preference name="AndroidExtraFilesystems" value="files,cache, sdcard, cache-external, files-external" />
</widget>
///////////////////////////////////////////////////////////

se tutto e' andata a buon fine si trovera' il file myfile.txt nella cartella Documenti

martedì 8 gennaio 2019

Mandelbrot su Olivetti M10

Per la rubrica Retrocomputing Estremo insieme di Mandelbrot su Olivetti, splendido portatile del 1983 marcato Olivetti ma non prodotto da Olivetti, con un processore 8085 (dove il 5 sta per 5 Volt, non c'e' bisogno della doppia alimentazione 5-12V) a 2.4 MHz

25 minuti di calcolo per una griglia 64x44 con soglia di 20 cicli utilizzando Virtual T, un emulatore per Olivetti M10 e TRS-80
Il codice BASIC e' stato adattato partendo dalla base di Rosetta Code






Perche' ho usato un emulatore....non ho nella mia collezione un Olivetti M10??
Errato serial 40301385 24K perfettamente funzionate




lunedì 7 gennaio 2019

Interagire con DynamoDB con Lambda e API Gateway

Un sistema per interagire con DynamoDB mediante una funzione Lambda triggerata da API Gateway




Prima prima cosa ho creato a mano una tabella in DynamoDB con due colonne nome (stringa) ed indice (numerico)

La funzione Lambda per interagire con DynamoDB necessita di permessi. Per rendere le cose piu' semplici ho usato i permessi piu' estesi che corrispondono al ruolo AmazonDyamoDBFullAccess (per creare il ruolo si va in consolle di AWS, si apre IAM, Ruolo, Crea Ruolo, si selezione il servizio Lambda e si spunta AmazonDyamoDBFullAccess) Dopo aver salvato il ruolo con un nome si modifica il Ruolo di Esecuzione nella finestra della funzione Lambda impostando il nuovo ruolo

La funzione Lambda di seguito mostra un insertItem ed un getItem condizionato al valore dell'indice numerico

================================================
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();

exports.handler = function(event, context) {
  
  var tableName = "bollettini";
var item = {
    nome: "Federico",
    indice: Number(4)
}
var params = {
    TableName: tableName,
    Item: item
};


    dynamo.putItem(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);               // successful response
    });
  
  var cb = function(err, data) {
    if(err) {
      console.log('error getItem: ',err);
      context.done('Unable to getItem', null);
    } else {
      if(data.Item && data.Item.nome) {
        context.done(null, data.Item);
      } else {
        context.done(null, {});
      }
    }
  };
  dynamo.getItem({TableName:"bollettini", Key:{indice:2}}, cb);

};
================================================

A questo punto per eseguire la Lambda e' necessario impostare un trigger che nel mio caso e' API Gateway. Dalla consolle di AWS si sceglie API Gateway, si selezione Create API, si indica il nome, Nella pagina successiva si clicca sul menu' a tendina Actions e si sceglie GET. Si apre una pagina sulla destra in si inserisce  l'ARN della Lambda e si salva. A questo punto si pubblica la API e si avra' come risposta un link del tipo https:/xxxxxxxx.execute-api.eu-west-1.amazonaws.com/test/

Puntano il browser al link indicato si mettera' in esecuzione la funzione Lambda

venerdì 4 gennaio 2019

Intel Edison: Batteria RTC o UPS

Ho ripreso la Intel Edison dal cassetto per un progetto che prevede di salvare dati da un GPS.
La Edison non sara' connessa ad una rete WiFi e quindi non e' possibile ricavare data/ora via NTP


Intel Edison dichiara nelle specifiche di montare un RTC (anche se non c'e' l'alloggiamento della batteria) rispettivamente sul pin 23 del modulo Edison od al pin 5 del J18 del mini breakout
Io in realta' uso il breakout Arduino e si trova solo il connettore J2 con indicazione BATT. Attandoci una LiPO che questa non funziona solo come batteria tampone per RTC ma funziona come un UPS per tutta la scheda (e quindi secondariamente mantiene vivo anche RTC)

In conclusione con il breakout Arduino non ha una connessione diretta con l'RTC, la batteria esterna alimenta tutta la scheda

giovedì 3 gennaio 2019

Salvare dati da seriale in blocchi orari

Una soluzione semplice per un problema: lo scopo e' registrati i dati derivanti in continuo da un GPS via seriale su file di dimensioni in base ad un'ora di acquisizione



Per fare cio' viene in aiuto il comando bash timeout che permette di interrompere dopo un certo numero di secondi un comando di lunga (od infinita esecuzione). Dopo essere passata un'ora viene di nuovo riavviato il comando per creare il nuovo file orario

-----------------------------------------------------------------
#!/bin/sh
while true
do
        timeout -s 15 3600 /home/root/gps_data.sh
done
-----------------------------------------------------------------

con il seguente semplice comando si invia tutto il flusso dati dalla seriale su USB verso un file

gps_data.sh
-----------------------------------------------------------------
(stty raw; cat> /media/sdcard/`date +%y%m%d%H%M`.txt) < /dev/ttyACM0
-----------------------------------------------------------------

in generale ho visto che il GPS produce circa 150Kb al secondo

mercoledì 2 gennaio 2019

Arduino GPS Datalogger

Ho provato a riconvertire un vecchio progetto in un GPS Datalogger
Lo shield aggiunto presenta un lettore SD Card ed un modulo DS1307 con il GPS collegato su Software Serial


I principali problemi:
1) pur acquisendo a 9600 dalla seriale ho scoperto che la scrittura della SD Card e' piu' lenta ..da questo la necessita' di fare un buffer. La scrittura di un blocco di byte e' molto piu' veloce di aprire il file in append, scrivere il byte, chiudere il file

2) il nome del file di acquisizione (che viene creato sulla base del tempo acquisito dall'RTC del DS1307) deve essere nel formato 8+3 del vecchio MSDOS (nel mio caso ho preferito usare due caratteri per mese, due carattteri per giorni, due caratteri per ora ed infine due caratteri per i minuti di inizio acquisizione)

3) questo semplice script segnala comunque che la memoria dell'Arduino e' ad limite critico

non ho ancora provato la funzione di deep sleep

--------------------------------------------------------------------------------------
// Low Power header
#include "LowPower.h"

// RTC headers
#include <Wire.h>
#include "RTClib.h"

// SD Card headers
#include <SPI.h>
#include <SD.h>

// Seriale dove invia il GPS
#include <SoftwareSerial.h>


RTC_DS1307 rtc;

const unsigned long SECOND = 1000;
const unsigned long HOUR = 3600 * SECOND;

unsigned long contatore = 0;
const unsigned int dim_buffer = 250;
byte SerialData[dim_buffer]; 

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 10;
char incomingByte = 0;   // for incoming serial data

char filen[10];
String filename;


// impostazione della seriale secondaria del GPS
SoftwareSerial mySerial(8, 9); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }

  // inizializzazione RTC
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  // Inizializzazione SD
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    while (1);
  }

  mySerial.begin(9600);

  contatore = 0;

  Serial.println("Inizializzazione terminata.");
}

void loop() {

  DateTime now = rtc.now();
  
  sprintf(filen, "%02d%02d%02d%02d.txt", now.month(), now.day(), now.hour(), now.minute());
  String filename(filen);
  delay(2500);

  for (int i=0; i <= 100000; i++){
        contatore = 0;
        while (mySerial.available()) {
            SerialData[contatore] = mySerial.read();
            contatore++;
          }

      
        File dataFile = SD.open(filename, FILE_WRITE);
            if (dataFile) {
              for (int s=0; s < contatore; s++){
                  dataFile.print(char(SerialData[s]));
              }
              dataFile.close();
            }
          
  }
  Serial.println("Finita acquisizione");

  //entra in sleep mode
  delay(HOUR);
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,SPI_OFF, USART0_OFF, TWI_OFF);

}

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