-
See attached file ServeHello3.post.js
The first case
var SSID1="faux"; var key1= "a6a69"; var SSID2="faux2"; var key2= "a6a70"; var SSID=SSID1; var key=key1;
1v94 Copyright 2016 G.Williams >Start Start connection process end require end test 0 =undefined Reset the ESP8266 end reset Hello World Connecting to WiFi faux end connect Hello World Hello World Hello World null IP= 192.168.1.9 null Wi-Fi Connected
And the other case
var SSID1="faux"; var key1= "a6a69"; var SSID2="faux2"; var key2= "a6a70"; var SSID=SSID2; var key=key2;
1v94 Copyright 2016 G.Williams >Start Start connection process end require end test 0 =undefined Reset the ESP8266 end reset Hello World Connecting to WiFi faux2 end connect Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World WiFi connect failed: FAIL errr 1 Hello World faux Start Start connection process end require end test 0 Reset the ESP8266 end reset Hello World Connecting to WiFi faux end connect Hello World Hello World Hello World null IP= 192.168.1.9 null Wi-Fi Connected >
-
Annotate the report descriptor
/* Annotate the report descriptor http://www.usbmadesimple.co.uk/ums_g_an_ms_8.gif */ /* Copyright (c) 2015 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. */ /* var mouse = require("USBMouse"); setWatch(function() { mouse.send(20,20,mouse.BUTTONS.NONE); // X movement, Y movement, buttons pressed }, BTN, {debounce:100,repeat:true, edge:"rising"}); */ /* E.setUSBHID ⇒ (top) Call type: E.setUSBHID(opts) Description USB HID will only take effect next time you unplug and re-plug your Espruino. If you're disconnecting it from power you'll have to make sure you have save()d after calling this function. Note: This is only available in devices that support USB HID (Espruino Pico and Espruino WiFi) Parameters opts - An object containing at least reportDescriptor, an array representing the report descriptor. Pass undefined to disable HID. */ E.setUSBHID({ reportDescriptor : [ 0x05, 0x01, //Usage Page (Generic Desktop Controls) 0x09, 0x02, //Usage (Mouse) 0xA1, 0x01, //Collection (application) 0x09, 0x01, //Usage (Pointer) 0xA1, 0x00, //Collextion (Physical) 0x05, 0x09, //Usage Page (Button) 0x19, 0x01, //Usage Minimum (1) 0x29, 0x03, //Usage Maximum (5) 0x15, 0x00, //Logical Minimum (0) 0x25, 0x01, //Logical Maximum (5) 0x95, 0x03, //Report Count (3) 0x75, 0x01, //Report Size (1) 0x81, 0x02, //Input (Data, Variable,Absolute,Bit Field) 0x95, 0x01, //Report Coint (1) 0x75, 0x05, //Report Size (5) 0x81, 0x01, //Input (Constant, Array, Absolute, Bit Field) 0x05, 0x01, //Usage Page (Generic Desktop Controls) 0x09, 0x30, //Usage 00 0x09, 0x31, //Usage (X) 0x09, 0x38, //Usage (Wheel) 0x15, 0x81, //Logical Minimum(-127) 0x25, 0x7F, //Logical Maximum(127) 0x75, 0x08, //Report Size (8) 0x95, 0x03, //Report Count (3) 0x81, 0x06, // Input (Data, Variablr,Relative, Bit Field) 0xC0, //End Collection 0x09, 0x3c, // ????? 0x05, 0xff, 0x09, 0x01, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x02, 0xb1, 0x22, 0x75, 0x06, 0x95, 0x01, 0xb1, 0x01, 0xc0 //end collection ] }); exports.BUTTONS = { NONE : 0, LEFT : 1, RIGHT : 2, MIDDLE : 4 }; exports.send = function(x,y,b) { E.sendUSBHID([b&7,x,y,0]); }; /* E.sendUSBHID ⇒ (top) Call type: E.sendUSBHID(data) Parameters data - An array of bytes to send as a USB HID packet Returns 1 on success, 0 on failure */
-
I've been searching for some Vogan poetry to further understand what is going on. Some of it gets really deep in the weeds.
Here is a link that seems to be about the right level to start with.It covers the hardware and bus messages but importantly the Descriptors that are used in the module.
This tool looks like it could be useful for creating a descriptor
HID Descriptor Tool from USB.org
@Gordon Espruino continues to amaze!
-
Had time to try the mouse driver today. Here's the code:
//mymouse.js // 15 Nov 2017 // // Use pushbutton on pin B3 to reset // Loads mouse driver into the USB boot // Every second move mouse cursor by 20 pixels // in a square pattern // //load and save the program // unplug and replug the Pico USB // mouse cursor should be moving in square pattern // reconnect to WebIde // mouse cursor still moving // Type reset() in left pane of WebIde // Type save() in left pane of WebIde var mouse = require("USBMouse"); // A way back to normal just in case var but1=B3; setWatch(function(){ console.log("endit"); reset(); },but1, {debounce:100,repeat:true, edge:"falling"}); var i=0; setInterval(function () { //console.log(i); switch (i){ case 0: mouse.send(0, 20, mouse.BUTTONS.NONE); // X movement, Y movement, break; case 1: mouse.send(20, 0, mouse.BUTTONS.NONE); // X movement, Y movement, break; case 2: mouse.send(0, -20, mouse.BUTTONS.NONE); // X movement, Y movement, break; case 3: mouse.send(-20, 0, mouse.BUTTONS.NONE); // X movement, Y movement, break; } i++; if( i>3) i=0; }, 1000);
It's interesting that the WebIde still talks through the USB port with the mouse functions.
-
A question concerning this example page.
Espruino USB HIDIf you copy one of the examples into the WebIde, send it to a Pico, and save it, how can you restore the Pico to its original state?
Perhaps rig a push button on a pin and do a setwatch on that pin that does a reset()? -
Hi @tbd. Lots of Midi possibilities. I'm just crawling around the basic Vogan poetry at this point, and will be glad to get USB Midi to connect with a Pico. Hopefully the HID info will transfer for a Bluetooth connection later on.
Here are links I've glanced at today:
Also looked at USB sniffer programs for a debug method.http://www.usb.org/developers/docs/devclass_docs/midi10.pdf
-
Look at the attached HTML files in the link @allObjects supplied above.
-
Here is a snippet of code from the script section of an HTML document. A button press event triggers the JSONpost function.
As written it sends an 'A'. The Espruino code sees the 'A' and sends some data back in S.I think there is a way to insert the message length as well, but that work is currently archived.
function JSONpost(){ //code to post the Postobj to the server and get a reply var yhttp = new XMLHttpRequest(); yhttp.addEventListener("error",JSONpost1); yhttp.open("POST","CMD", true); yhttp.send("A"); // text to send yhttp.onreadystatechange = function() { if (yhttp.readyState == 4 && yhttp.status == 200) { var S=JSON.parse(yhttp.responseText); // the reply is in S }//endif };//end onreadystate function }//end JSONpost
Additional info can be had here:
Add Event Listener -
Hi @Gordon
The following link has Ruby (sonic pi)code that takes a CSV Midi file as input and outputs CSV files for each Midi track as a Midi note number, note length, and velocity (amplitude).
The conversion is a bit tricky as Midi CSV has column that contains a clock count ( Tempo cmds can alter the clock speed, followed by the Note On or Note off commands and the Velocity(Amplitude). A Note On with velocity zero is really a Note Off.
Sonic Pi doesn't use a master clock just a note number and duration. Not a problem if there are no chords, but gets complicated when a Midi track contains chords, especially pyramid chords.Here is a sound using theses Midi translation techniques on a Sonic Pi platform:
I'll give the waveform stop another try. I think you get an error message if you try to stop it before it finishes.
As for synth or sound chips, Midi would be nice but I2C or SPIand Espruino would work as well.
Adafruit has a bunch of Arduino Midi projects and kit as well.
From the main Midi spec site, the Din plug goes to an optoisolator and some driver chips into a UART. My Midi Keyboard uses either Din or USB for connection. The USB driver shows a generic audio device driver. Some keyboards use Bluetooth as well. I intend to explore the HID requirements for this at some point. Of course more code to do the Midi in binary format would be needed. As a start, setup the HID for the Espruino USB, pair with the PC, then send some Midi phrases out the port and see if they show up in the Midi Editor program mentioned before. That could then expand into a button presses into the Espruino to send Midi canned commands ( a drum pad device)
-
-
To create a Midi file using the computer keyboard or a USB (Piano like) keyboard and play it using the sound card. Reads and saves files as well. Records sound as wav file.
Midi EditorTo parse Midi at the byte level consult the Vogan poetry found here
Midi Specification
Midi Msg Summaryor in human readable form convert a Midi file to text using:
Midi to CSV and backa b c d e f g 0 0 Header 1 7 384 1 0 Start_track 1 0 Text_t "Creator: GNU LilyPond 2.6.4.3 " 1 0 Text_t "Generated automatically by: GNU LilyPond 2.6.4.3 " 1 0 Text_t "at Mon Mar 6 20:16:27 2006 " 1 0 Text_t "at Mon Mar 6 20:16:27 2006 " 1 0 Title_t "Track 0" 1 0 End_track 2 0 Start_track 2 0 Key_signature -1 "minor" 2 0 Time_signature 2 1 18 8 2 0 Title_t "\new" 2 0 Tempo 500000 2 6144 Note_on_c 0 69 127 2 6912 Note_off_c 0 69 64 2 6912 Note_on_c 0 74 127 2 7680 Note_off_c 0 74 64 One thought was to adapt the following to Espruino. It uses square, sine and triangle waves.
Is there an easy way to get theses waveforms using PWM?When using the DAC to play a sound sample it would be useful to be able to stop the sample output at some point mid stream. Is there a way to do this?
As time allows I'll setup and record the sound from the code above and post it.
Is there a synthesizer or sound chip that uses I2C or SPI that Espruino could control?
-
Oops
The Rests in the melody seemed to be missing. This is the fix. Relocate the getTime().
music.prototype.play=function(note){ // console.log(note,this.Spkr); if (this.onoff>0) return; console.log(note,midi2tone(note)); var octave=Math.log(2); var halftone=octave/12; this.start=getTime(); //moved this from below if(note===null)return; // a rest note=note-60; var tone=Math.exp(note*halftone); this.freq(261.63*tone); //C4 Middle C Midi note 60 // this.start=getTime(); //move this from here };//end play
-
Musical Steganography
This uses a Pico with PWM outputs connected to a point using 10 k resistors. The point connects to ground through a parallel combination of a 10k resistor and 1 1.0 uf Capacitor.
An isolated amplifier input is connected beween the point and ground.
A USB microphone and Audacity was used to record the resulting music link is here:Files:
Steganongraphy1.js -
Playing Piano Midi Notes on an Espruino Original Board
Using the Espruino examples found here:
A recording of Middle C played on a piano was found here:
As per the example Audacity found here:
Audacitywas used to create an audio sample at 8 kHz rate in unsigned 8 bit format.
The function get_freq(note) was constructed so that the playback rate of the sound sample can be adjusted to change the pitch of the note. The note is specified as a Midi note number.
Middle C is Midi note number 60 (aka C4), C above middle C (aka C5) is midi note number 72.function get_freq(note){ //note is midi note note=note-60; var octave=Math.log(2); var halftone=octave/12; //console.log(note); var tone=Math.exp(note*halftone); var freq=8000*tone; //C4 Middle C Midi note 60 return freq; }// end get_freq
The sample was converted to a string and coded into the program
// 8 bit unsigned Piano C4 sampled at 8 kHz Piano= "\x7f\x80\x80\x7f\x80\x7f\x80\x80\x80\x7f\x80\x7f\x80\x80\x80\x80\x80\x7f\x80\x7f\x80\x7f\x80\x80\x80\x80\x80\x80\x7f\x80\x7f\x80\x7f\x80\x7 ... \x80\x80\x81\x80\x80\x81\x81\x81\x81\x80\x81\x82\x82\x82\x82\x82\x81\x80\x7f~}|||}}~~\x7f" ;
The chromatic scale is played by this code:
k=0; var ww = new Waveform(Piano.length);//,{bits:16}); ww.buffer.set(Piano); note=60; analogWrite(A4, 0.5); ww.startOutput(A4,get_freq(note)); // this event doesn't fire unless repeat is true ww.on('buffer',function(data) { console.log("B"); k++; if (k>3) ww.stop(); }); ww.on('finish',function(data) { console.log("F");//+data); note++; k=0; if (note>72) note=60;//{ ww.startOutput(Aout, get_freq(note));//,{repeat:true}); //} });
Discussion
Other instrument samples are widely available on the Web. (Orchestras)
The tempo of the notes increases with pitch. How to solve this?
With only 2 DACs, polyphony is limited. Using PWM can produce synthesized sounds.attached files
Piano1 .js
-
There are a number of examples on this site for creating musical sounds. Thank you for the help in creating this post.
When I bought a Raspberry Pi, I discovered the Sonic PI software that also runs on PC, Mac and Linux.
Program uses a modified Ruby interpreter.I wondered if something like Sonic Pi could be implemented using Espruino, at least a small subset.
Here is a first attempt://music.js // 1 Nov 2017 // Tested on a Pico // make music in a fashion similar to Sonic PI // http://sonic-pi.net/ // // Hardware // Connect an amplified speaker input to ground and the Speaker pin // as defined here var Speaker=A5; //A9; // use this to find a suitable pin //analogWrite(); /* Pico pins Suitable pins are: A0 A1 A2 A3 A5 A6 A7 A8 A9 A10 A11 A15 B0 B1 B3 B4 B5 B6 B7 B8 B9 B10 B13 B14 B15 =undefined */ var Tempo =1.0; // changes tempo of the music // define some note lengths var Whole=1.0; var Half=Whole/2.0; var Quart=Half/2.0; var Eighth=Quart/2.0; // Use this table to write the song as a seried of Midi notes, // and durations // http://www.electronics.dit.ie/staff/tscarff/Music_technology/midi/midi_note_numbers_for_octaves.htm // Tune is C4 Major scale C4 is middle C, Midi note 60 var tune=[[60,Quart], [62,Eighth], [64,Quart], [65,Eighth], [null,Half], // a musical rest [67,Quart], [69,Eighth], [71,Quart], [72,Eighth] ]; var octave=Math.log(2); var halftone=octave/12; function freq(f) { if (f===0) digitalWrite(Speaker,0); else analogWrite(Speaker, 0.5, { freq: f } ); } function soundoff(){ digitalWrite(Speaker,0); } function play(note){ if(note===null)return; // a rest note=note-60; //console.log(note); var tone=Math.exp(note*halftone); //console.log(tone); freq(261.63*tone); //C4 Middle C Midi note 60 }//end play function wait(a,c){ var b=getTime(); if (b>=(a+c)) return b; return a; } var a; var b; var i=0; a=getTime(); //console.log(a); setInterval(function () { //if(tune[i][0]!==null) play(tune[i][0]); b=wait(a,tune[i][1]*Tempo); if(b!=a){ a=b; soundoff(); i++; } if(i>=tune.length) clearInterval(); }, 10);
-
-
Try something like this
//RNG.js // Generates a 16 byte block of random numbers using AES //RNG.js function RNG(){ this.key1=new Uint8Array(16); this.R=new Uint8Array(16); this.plain=new Uint8Array(16); }//end RNG RNG.prototype.random=function(A){ var i; E.srand(E.hwRand()); //randomize for(i=0;i<16;i++)this.plain[i]=(Math.random()*256)%256; this.R=AES.encrypt(this.plain,this.key1); for(i=0;i<16;i++)A[i]=this.R[i]; };//end random RNG.prototype.setup_random=function(){ for(var i=0;i<16;i++){ E.srand(E.hwRand()); this.key1[i]=parseInt((Math.random()*256),10); } };//end setup_random //exports = RNG; function testit(){ var i; var A=new Uint8Array(16); // var W=new (require("RNG"))(); var W=new RNG(); W.setup_random(); for(i=0;i<16;i++){ W.random(A); console.log(A); } } testit();
-
Thanks DrAzzy. It looks like it uses a local router based address. Is that correct?
I've done some digging and came up with this possible solution;
A javascript project that connects Amazon Echo to a coffee pot
https://www.mybridge.co/view/176842
It makes use of Google IFTTT and a local tunnel
IFTTT is used to connect the Echo (Google IFTTT) it’s a Google product and goes beyond Amazon products
https://en.wikipedia.org/wiki/IFTTT
To expose the server code to the Internet they used a tunnel
https://www.npmjs.com/package/localtunnel
The code for tunnel
-
I've been looking at the Amazon Alexa devices and wondering if they could be used with a WiFi enabled Espruino device.
The Alexa works with AC switch devices but uses a offsite server as part of the link.
Is there a way to have Alexa send a message to an Espruino device though my local router?A different idea uses the speech to text available in Android to send the message.
I've used online service to find the IP address of my router, but how do you get a message to a specific device connected to the router (a sub-address)?
-
The Datasheet can be found at:
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-DS001-18.pdfLook at the section on I2C
If SDO is tied to ground the slave address is 0x76
If SDO is tied to Vcc the slave address is 0x77
I don't have either a Puck or the BMP chip, so I hope this helps. If not maybe someone else can help. -
-
The Vogon poet of the datasheet didn't provide any handshake information so I'm where the Dragons roam as to why this change worked. If planning a mission to Mars using this code, it would be prudent to ring up Bosch and ask. The other alternative is to look at their coding examples for a hint. It works on my table but will it work in other environments?
Cleaning it up a bit:
The code
The left pane output, note faux2 is not in range, but faux is