Read USB Serial data and write to SD card

Posted on
  • Hello,
    How do I go about reading Serial data coming from a PC via USB and write that to the SD card?
    I've tried the code below but nothing gets written to data.txt and LED2 doesn't flash.

        function onInit() {
        digitalWrite(LED2,1);
        var cmd="";
        var fs = require("fs");
    
        Serial1.setup(9600/*baud*/);
        Serial1.on('data', function () { 
          digitalWrite(LED2,0);
      
          cmd+=data;
          var idx = cmd.indexOf("\r");
    
          while (idx>=0) {
            var line = cmd.substr(0,idx);
            cmd = cmd.substr(idx+1);
            var s = "'"+line+"' = "+eval(line); 
            idx = cmd.indexOf("\r");
        
            fs.appendFile("data.txt", s+"\r");
          }
          digitalWrite(LED2,1);
      
        });  
        }
    
  • Well, looks like what you have there should work - but you're using Serial1 which is an actual serial port - not USB. Try removing Serial1.setup, and change the next like to USB.on.

    You may also need to move the console over to another place so that the data you're sending over USB doesn't get interpreted as JavaScript. You can move it out the way with LoopbackA.setConsole() - but after that you will probably need to reset Espruino with the button before you can reprogram it.

  • Still nothing I'm afraid. Is it possible to send data to Espruino while watching it in the IDE over bluetooth?

    To give you some more info on what I'm trying to do, my goal is to use Espruino as the controller for a TV Ambilight system. The software on the PC is AmbiBox (http://www.ambibox.ru/en/index.php/Main_­Page) it analyse whatever is on the PC screen into colour blocks and send it over serial port to Espruino which will then control an RGB LED strip.

  • Yes, what you want to do should work fine... And yes, you can still control Espruino over Bluetooth - just make sure that you do use Serial1.setConsole beforehand.

    But actually I just saw something: in your code example you write Serial1.on('data', function () { but the function actually needs the data argument to be passed in... Try: Serial1.on('data', function (data) {

  • Hey Gordon,
    Working with USB and Bluetooth is working well. Serial1.setConsole(); was the trick.
    Now the PC is sending data to Espruino and I can read it over Bluetooth but I'm not sure what encoding it's in? I've tried many options of toString() parseInt() and reading the Hex in a Hex decoder. Below is a sample of the data I'm getting and I've attached a large file with more that Espruino saved to the SD card.
    Do you know what format this is in and how to decode it?

    ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,­+3
    ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,­+3
    ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,+3ô/,,­+3
    

    Running this through ([http://frhed.sourceforge.net] Frhed Hex editor) I get something more readable but I'm still not sure what format it is in:

    <bh:00><bh:f4><bh:11><bh:1f>/<bh:10><bh:­1d>,<bh:10><bh:1d>,<bh:11><bh:1c>+3
    <bh:00><bh:f4><bh:11><bh:1f>/<bh:10><bh:­1d>,<bh:10><bh:1d>,<bh:11><bh:1c>+3
    <bh:00><bh:f4><bh:11><bh:1f>/<bh:10><bh:­1d>,<bh:10><bh:1d>,<bh:11><bh:1c>+3 
    

    1 Attachment

  • Which one of the various devices is AmbiBox set to output as? It's possible that another type would output as something more human readable (or that there'd be documentation on it somewhere)?

    As far as I can see from the contents of the text file, you've got blocks of 15 bytes... I don't know where they start or end, but they seem like they could be something like:

    33 00 F4 RR GG BB RR GG BB RR GG BB RR GG BB
    

    That's only 4 LEDs worth of data though... do you think that's right?

    So to read it you could probably do something like you've got already, but with:

    var idx = cmd.indexOf("\x33\x00\xF4");
    

    and then once you've extracted the 12 bytes string, you could shove it right into SPI.send4bit to control some WS2811 LEDs (although it's possible the colour channels would be in the wrong order).

  • I've tried all the of the different AmbiBox outputs, most of them sent data down the COM port but Espruino still only receives the same unreadable text.
    I saw this pattern that appear to be the beginning of each line but I'm not sure how to use that to split up the data and then decode it.

    Ada\x00\x03V
    

    I again tried the example here http://www.espruino.com/USART using this new line breaker but it is still unreadable:

    Vª²»«³¼®·¿°·¿
    

    I'm not sure why to try next?

  • The output wouldn't be readable as it's just a string of binary data - ideally you'd shove it straight into some LEDs so you could see it...

    You should be able to output the actual values doing something like this though:

    console.log(data.split("").map(function(­n) { return n.charCodeAt(0); }).join(" "))
    
  • I am new to Espruino and have just had a lot of difficulty with this. For that reason I am posting my solution for future reference. Sorry to raise the dead.

    The following code allows me to toggle LED1 via echo 'a' > /dev/tty.usbmodem1411. I am not sure if the tty would be different for another user(?)

    var state = false;
    LED1.write(state);
    
    Serial1.setup(9600);
    Serial1.setConsole();
    Serial1.on('data', function (data) {
      state = !state;
      LED1.write(state);
    });
    
  • Hi - thanks for posting up...

    The TTY would almost certainly be different, but a command like echo 'a' > /dev/tty.usbmodem* would probably be fine.

    I'm not sure about the code that you post though - is that for an Espruino board? When Espruino is connected by USB, data comes in on the USB object, so I'd imagine that the following:

    USB.on('data', function (data) {
      state = !state;
      LED1.write(state);
    });
    

    is more likely to work. Maybe you had the code in there already, and it only started working when you moved the console away from USB with: Serial1.setConsole();?

  • Just to add, it depends what you want to do, but often for this kind of thing it's easier to work with the console interface rather than against it. You can just send the JS command directly from your Mac:

    echo -e "digitalWrite(LED1, on=!on);\n" > /dev/tty.usbmodem*
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Read USB Serial data and write to SD card

Posted by Avatar for Owen @Owen

Actions