Avatar for Drumline18

Drumline18

Member since Dec 2019 • Last active May 2020
  • 2 conversations
  • 9 comments

Most recent activity

    • 6 comments
    • 3,064 views
  • in ESP8266
    Avatar for Drumline18

    English is not my native language, sorry if my explanations are not clear enough.

    I don't want to bother Gordon with the title-thingie but I assure you I'm supporting the project on Patreon. Thank you for your answer.

    There is no complete code. I was playing with it in the same way shown in the video at the top of Making Music, using the WebIDE. But here is the complete code from the example, in one block:

    var BUZZER=A9;
    
    function freq(f) { 
      if (f===0) digitalWrite(BUZZER,0);
      else analogWrite(BUZZER, 0.5, { freq: f } );
    }
    
    var pitches = {
      'a':220.00,
      'b':246.94,
      'c':261.63,
      'd':293.66,
      'e':329.63,
      'f':349.23,
      'g':392.00,
      'A':440.00,
      'B':493.88,
      'C':523.25,
      'D':587.33,
      'E':659.26,
      'F':698.46,
      'G':783.99
    };
    
    function step() {
      var ch = tune[pos];
      if (ch !== undefined) pos++;
      if (ch in pitches) freq(pitches[ch]);
      else freq(0); // off
    }
    
    var tune = "c    c    c   d    e   e  d   e    f   g   C  C C   g  g g   e  e e   c  c c  g    f  e   d c";
    var pos = 0;
    
    setInterval(step, 100);
    

    You can see in that code where the BUZZER terminology comes from. But I have both a passive buzzer and a speaker salvaged from a screen (no markings). Both exhibit the same behavior, and the LED too, so that's why I'm targetting the MCU/code now. No capacitors, no resistors. The buzzer has polarity. It's connected GND to GND and + to a pin, directly, just like in the tutorial.

    The confusion over L9 stating I can change frequencies instantly stems from the fact the problem depends on the state of the pin I'm trying to change.

    If a pin is already using PWM (i.e. by a previous analogWrite 0.x), the changes are instant.
    But, if the current state of the pin is either exactly 0 or 1, there is a delay before changes occur.
    But also, transitioning from 0 or 1 to an intermediary value on another pin will hang other pins.

    1 -> 0.x = delay
    0 -> 0.x = delay
    0.x -> 0.y = instant
    0.x -> 0 = instant
    0.x -> 1 = instant
    0.x -> freq change => instant

    Its like... sticking to the 1 and 0. I don't know how to better explain it. It may require a video (tomorrow once everyone is awake).

    Here is the code I am using to get that 1700ms figure :

    analogWrite(PIN, 0.5, {freq:1000});
    setTimeout(()=>{analogWrite(PIN,0)}, 1700)
    

    By playing with the timeout delay I get it to where I can hear it start, resulting in a extremely short beep. At 1700 I can still hear it but at 1690 I can't.

    I get the exact same behavior, down to the 1700ms figure, with 2 different boards of different manufacturers. I can't find the proper datasheets (I don't know which ones are the proper ones) but I highly doubt it makes a difference. One is ESP-12F and the other is ESP8266MOD. I tried all pins with the buzzer and used onboard LEDs for the visual tests.

    Following your link to source code I am reading the implementation for ESP8266.
    The code executes differently if Hardware PWM is defined, notably defaulting the freq at 50 in software mode and 1000 in hardware mode.

    https://github.com/espruino/Espruino/blo­b/624d6f2c700bfbf08e4a7eb7d282bd57648470­56/targets/esp8266/jshardware.c#L609

    Whenever I test without adding a frequency I get the same sound as if I try with freq : 50, leading me to believe it is defaulting to software right away. I don't understand much further in the source though.

  • in ESP8266
    Avatar for Drumline18

    I'm trying to add a speaker to a project, following the Making Music page using an ESP8266 board (NodeMCU v3).

    The example is using analogWrite() to create sound on the speaker and it works.
    When the speaker is emmiting sound, I can enter new analogWrites with different frequencies to change the pitch and that works instantly.

    The problem is when the speaker is going from silent to emmiting sound. There is quite a long delay before it does anything (~1700ms). Is that normal behavior with the ESP8266 ?

    The final desired product chimes when a door is opened and 1700ms delay makes it weird.

    Example:

    // starting from silent
    let BUZZER = NodeMCU.D1
    // action : activate buzzer at 1000 freq
    analogWrite(BUZZER, 0.5, {freq:1000});
    // result : ~ 1700ms delay... then sound
    
    // action : change freq to 1500
    analogWrite(BUZZER, 0.5, {freq:1500});
    // result : instant pitch change
    
    // action : stop buzzer
    analogWrite(BUZZER, 0, {freq:1500});
    // result : instant stop
    
    // action : activate buzzer again
    analogWrite(BUZZER, 0.5, {freq:1000});
    // result : ~1700ms delay then sound
    
    

    So, copy-pasting the whole example code results in no sounds as there are no notes lasting over 1700ms.

    Example 2:
    I can also observe the same effect visually with the following snippet (breathing LED) :

    setInterval(()=>{ analogWrite(D2, (Math.sin(getTime()) / 2.01) + 0.5) }, 10) 
    

    And then at any point sending analogWrite(D2,0) or digitalWrite(D2,0) (or 1) will pause the effect for roughly 1700ms again. Actually, sending analogWrite between 0 and 1 (exclusively) to any pin that is not already been "activated" by another analogWrite will pause the effect on the unrelated D2 pin!

    What I have tried :

    1. Calling analogWrite twice
    2. Using digitalWrite for 0 and 1 values
    3. Using analogWrite 0 and 1 with and without frequency
    4. Using analogWrite in a setTimeout
    5. Using values very close to 0 and 1 as "off" state (that kinda works but big cheat as it is still audible from closer)
    6. Using a different ESP8266 dev board

    Bonus info:

    In the breathing LED effect snippet, I am dividing the sin of time by 2.01 instead of 2 which would allow the numbers to include 0 and 1. If I don't do so, the LED becomes unpredictable when going low, it can flash at full brightness for a very small amount of time, Im assuming when it reaches an actual 0 or 1, but the flash does not last 1700ms.

  • in ESP8266
    Avatar for Drumline18

    It works !

    I've received the NodeMCU board first.

    Plugging the rc522 module in the hardware SPI pins leads to crashing and breaking the IDEs console. Just connecting it, no running code. So until further investigation, no hardware SPI.

    Using software SPI and pins D1, D2, D3 and D4, it worked right away, using the NodeMCU prefix.

    For reference :

    let spi = new SPI();
    spi.setup({sck:NodeMCU.D2, miso:NodeMCU.D4, mosi:NodeMCU.D3});
    var nfc = require("MFRC522").connect(spi, NodeMCU.D1);
    

    I got everything else to work using software I2C too using D5 and D6.

  • in ESP8266
    Avatar for Drumline18

    Yesterday I tried to reverse engineer the MFRC522 library and I failed, receiving varying data depending largely on the SPI setup.

    I've also tried earlier versions of Espruino, just in case. No changes.

    The board I have, the Wemos D1 R1 is no longer in production, they are doing the R2 now, mostly pin changes apparently. But I can't help but wonder if that is the root of my problem.

    I should get the NodeMCUV3 and an ESP32 any time now. I'll try with that and make sure to keep this thread updated.

    'If you like you can flash the 4MB build after you got the MFRC522 working :)'

    I thought that was that I had going?? I got the 4MB version, in directory form and flashed it with :

    esptool.py --port COM3 --baud 115200 write_flash --flash_freq 80m --flash_mode qio --flash_size 32m 0x0000 boot_v1.6.bin 0x1000 espruino_esp8266_user1.bin 0x3FC000 esp_init_data_default.bin 0xFE000 blank.bin
    

    After running the esptool erase_flash, of course.

    'So go and get your Donated label below your Avatar.'

    I've become a small patron on patreon, I'll make sure to update that as well when I get back to full time employment.

    'Stopping Wifi is helpful during testing'

    I figured that would help with @allObjects's comment on the non-negotiable demands of the wifi stack. It didn't seem to affect the results I was getting (not like changing NSS pin or using software SPI)

    'got a pico, esp8266 and a MFRC522 on my desk and will give it a try.'

    If you get to dig deep, I'd be interested in what the communication looks like in a working MFRC522!

    Sooo... In the meantime I gave in to the dark side, plugged the MFRC522 in the Arduino Nano and wrote a small C script for it to be slave I2C and report back to the ESP8266 running Espruino. Within 30 minutes I was reading cards, that felt good.

    I'm not giving up on having it directly on an ESP, but I'll take a break from it until I get further gear (or the logic analyzer!). Thanks again for the answers.

  • in ESP8266
    Avatar for Drumline18

    'Spending countless hours on details others just left out ore did not think of to matter made me chip up the few extra bucks to buy Espruino hardware for which the Espruino Firmware and Software was built for[...]'

    Although I love how Espruino is currently implemented, I think I'll prefer donating directly to support the project instead of buying the boards. At the price points, donating and buying a Raspberry Pi Zero W makes more economical sense to me while allowing me to use fully featured JS and toolchains and not really supporting the "board building" effort part of the project. You guys seem to be more experienced than me with microcontrollers so maybe I'm just missing the point, please enlighten me. The fact I'm running JS and Wifi from this 2$ chip is what makes it interesting to me.

    Btw, I liked your abstraction layer for pin mapping[...]

    Thank you. Thinking about it, it would work, by using D pins instead of Numbers, essentially recreating a NodeMCU-like prefix for my board.

    At this point I'll share my exact errors and test script for reference and documentation.
    There doesn't seem to be a spoiler feature on the Forum so sorry for the long post.

    I built a script to test everything using the console :

    const MFRC522 = require("MFRC522");
    var nfc;
    var spi;
    
    const SPI_PINS = {
      sck: D14,
      miso: D12,
      mosi: D13
    };
    
    function softwareSPI() {
      spi = new SPI();
      spi.setup(SPI_PINS);
    }
    
    function hardwareSPI() {
      SPI1.setup(SPI_PINS);
    }
    
    function connect(_spi) {
      nfc = MFRC522.connect(_spi, D15);
    }
    
    function log(c) {console.log('Card : ', c);}
    
    function test() {
      nfc.findCards(log);
    }
    
    // softwareSPI() or hardwareSPI()
    // connect(spi) or connect(SPI1)
    // test()
    

    As you can see, it's not doing much at upload time, only definitions. I then run the commands that are commented, using the Espruino IDE console.

    Hardware SPI results :

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v04 (c) 2019 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    Flash map 4MB:512/512, manuf 0x20 chip 0x4016
    >
    >hardwareSPI()
    =undefined
    >connect(SPI1)
    =undefined
    >test()
    Uncaught Error: MFRC522 Request Error 12
     at line 1 col 189
    ...("MFRC522 Request Error "+a);a=this.r(20);return this.ra(18,...
                                  ^
    in function "req" called from line 1 col 34
    this.w(26,7);return 0<this.req(38).length
                                     ^
    in function "isNewCard" called from line 1 col 16
    this.isNewCard()&&a(this.getCardSerial()­)
                   ^
    in function "findCards" called from line 1 col 18
    nfc.findCards(log);
                     ^
    in function "test" called from line 1 col 6
    test()
         ^
    

    Software SPI results :

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v04 (c) 2019 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    Flash map 4MB:512/512, manuf 0x20 chip 0x4016
    >
    >softwareSPI()
    =undefined
    >connect(spi)
    =undefined
    >test()
    =undefined
    

    To make sure, I double checked that each D pins referenced was the actual physical pin I was plugging into, so I'm fairly sure that my wiring is fine, again.

    Removing each pin one by one changes the error code :

    All pins connected : Error 12
    Without NSS pin :    Error 158
    Without SCK :        Undefined
    Wihtout MOSI :       Undefined
    Without MISO :       Error 255
    Swapping MISO and MOSI : Error 255
    
    

    I'll try to dissect the MFRC522 library a little more tonight. If that doesn't do it, I'll wait for the NodeMCU and I'll try to get another RC522 module from another mfg. My local supplier seems to like Keyestudio alot.

    I may try flashing to an earlier version of Espruino too. Just in case.

    EDIT: typo 2020-01-01

  • in ESP8266
    Avatar for Drumline18

    Happy 2020 everyone!

    Thanks again for the answers.

    'Is an attempt to re-write that library underway?'

    Not really. I'm trying to understand how the current one works by dissecting it. If it has to come to a full re-write, Espruino will probably get "phase 2".

    'Double check the pin mode.'

    This somewhat gives me hope that my problem is still something fairly simple like that.
    However I'm not sure what pinMode each pin should be in!
    In my current test, with the same error 12 setup, before calling MFRC522.connect, all the affected (D14, D12, D13, D15) are "input_pullup". After calling it, the NSS pin is now "output".

    'Has the 'NodeMCU' prefix been attempted? '

    I stripped everything from the board, setup a breadboard with and LED and tested each NodeMCU pins. At this point, I'm fairly sure this 'prefix' is not useful to my board. Here are the results from the experiment :

    NodeMCU.D0   NOT OK      (D2 on board, GPIO16)
    NodeMCU.D1   NOT OK      (D3 on board, GPIO5)
    NodeMCU.D2   NOT OK      (D4 on board, GPIO4)
    NodeMCU.D3   NOT OK      (D8 on board, GPIO0)
    NodeMCU.D4   NOT OK      (D9 on board, GPIO2, ESP8266_LED)
    NodeMCU.D5   OK          (SCK_LED)
    NodeMCU.D6   OK
    NodeMCU.D7   OK
    NodeMCU.D8   NOT OK      (D10 on board, GPIO)
    NodeMCU.D9   BREAKS CMD  (D0 on board, RX, GPIO3)
    NodeMCU.D10  BREAKS CMD  (D1 on board, TX, GPIO1)
    NodeMCU.D11+ UNDEFINED   (11,12,13,14,15 undefined)
    // OK          Control + correct silk screen D pin
    // NOT OK      Control + Incorrect silk screen
    // BREAKS CMD  No more Espruino IDE console, unknown usability unplugged
    // UNDEFINED   These pins do not exist in the NodeMCU 'prefix'
    

    However the GPIO numbers visible from under the board are easy to use with the normal D pins.

    'save() with modules where .connect() initializes device (such as RFID reader MFRC522)'

    Good read, but I understand how save() works, at least I think I do. Getting the Espruino to work without a computer was 1st order priority on Day 1, coming from Arduino. If I can get even just one read from the RFID using Espruino, I will feel confident dealing with everything else.

  • in ESP8266
    Avatar for Drumline18

    Tonight is proving to be quite a learning experience.

    In the MFRC522 module :

    MFRC522.prototype.w = function(addr,data) {
      this.spi.write(addr, data, this.cs);
    };
    

    In the SPI reference :

    Parameters
    data, ... - One or more items to write. May be ints, strings, arrays, or special objects (see E.toUint8Array for more info).
    If the last argument is a pin, it is taken to be the NSS pin

    My "pins" are simple Numbers, not Pin objects.
    Inspecting the C file using the reference link, it looks like the function is looking for a Pin object. Link here, line 215.

    So here I'm thinking that is my problem, it doesn't know what the SS pin is.
    In fact the second phenomenon making me think about that is that the error code is the same as the pin number entered.

    So I re-read the Espruino on ESP8266 page, again, and again. Now I understand my WemosD1 object is no longer required. I can refer to the Dxx pins directly, by referencing the GPIO number instead.(Duh!). So I dropped my WemosD1 object to use D pins exclusively.

    Giving the MFRC522.connect function a proper Pin object changed the behavior drastically I think. I still get the same Error message, but the error code is now 12, regardless of what SS pins I use.

    Now I can't help but notice this is the exact same error code as in Github issue #258 previously linked.

    Their code was using software SPI, which I have just re-tried. MFRC522.findCards returns undefined without errors. Its not doing anything.

    Shorting MISO to MOSI allowed me to verify that both HW and SW SPI are working (following the quick tip from Gordon here).

    If I physically disconnect the SS pin, the error is 255. The error is consistent on 3 different pins now, D15, D16 and D0.

    Its getting late now.
    I'll have to take a look at the code on the Keyestudio Wiki, to compare it with the values in the MFRC522.js library. @Robin, sadly I cannot find the datasheet PDF you are referring to. The page you linked tells me there is no text there. And the page I was able to find only has a garbage PDF full with the same information as the wiki page.

    I did not need special numbers or modifications with the Arduino library, so I'm assuming they will be the same, unless they have something special for Keyestudio detection.

    I also want to try and communicate manually with the RFID sensor, essentially emulating what the library is trying to do.

    No success tonight but digitalWrite(myHopes, HIGH);

  • in ESP8266
    Avatar for Drumline18

    Thank you both for your prompt responses to this non-official board.
    Hope everyone is having good holidays.

    Pin mapping was the first issue I got to when getting this Wemos D1 (r1) board.
    So I created my own object to store the mapping to my board :

    const WemosD1 = {
      D0: 3,
      D1: 1,
      D2: 16,
      D3: 5,
      D4: 4,
      D5: 14,
      D6: 12,
      D7: 13,
      D8: 0,
      D9: 2,
      D10: 15,
      D11: 13,
      D12: 12,
      D13: 14,
      D14: 4,
      D15: 5
    };
    

    Simple numbers representing the GPIOXX equivalent from the ESP8266. D pins overlap each other (ie. D5 & D13 are GPIO14).
    This object was built using the silkscreen on the board itself. I have not tested every one of them yet. I will probably get around to it tonight.

    My SPI setup looks likes this : (GPIO equivalents in comments)

      SPI1.setup({
        sck: WemosD1.D5, // GPIO14
        miso: WemosD1.D6, // GPIO12
        mosi: WemosD1.D7 // GPIO13
      });
      
      // And then the MFRC522 
      const rfid = require('MFRC522').connect(SPI1, WemosD1.D2); //CS -> GPIO16 (also tried GPIO15)
    

    When comparing the GPIO pins to a pinout image or a bare ESP8266, it looks like it fits with the pins labeled MISO, MOSI and SCLK. GPIO15 being labeled as CS, it gives an error 15 instead of 16.

    I will have more time tonight to go through the jswrap C file.

    "I also solved this using a logic analyzer [...] around twenty dollars."

    Wow I didn't know something like this existed, at such a low cost. I must get one now.

    I will receive a NodeMCU V3 in a week or two, that should be the actual module that I will be implementing in my system. Hopefully the NodeMCU.XX pin mapping will work with this one.

    Professionally, I'm a front-end developer. I LOVE Javascript. I LOVE how Espruino implements it on microcontrollers. My javascript sketch is indeed about half the size the C one for the same tasks, and it feels much more elegant. Although for this time it might be more effort than C, I'm looking forward to the challenge.

    So tonight's jobs :

    • Verify my pin mapping object
    • Go through the jswrap C file that @MaBe linked to confirm pin mapping
    • Read on SPI communication (need more understanding) and try to confirm SPI communication is working.
    • Shopping for a logic analyzer

    EDIT: Formatting correction 2019-12-30

Actions