espruino / Espruino

The Espruino JavaScript interpreter - Official Repo
http://www.espruino.com/
Other
2.75k stars 739 forks source link

substr not available #2356

Closed kairos0ne closed 1 year ago

kairos0ne commented 1 year ago

I actual see a few issue here, the connection over BLE is unstable for some reason only connects intermittently.

Also I see this error substr is not available... seems odd as this std lib for JS

Here is the error:

BTN1 detected L
Device found
Got UART Service
{
  "write": function (a) {return new Promise(function b(g,e){a.length?(n.writeValue(a.substr(0,20)).then(function(){b(g,e)}).catch(e),a=a.substr(20)):g()})},
  "disconnect": function () {return k.disconnect()},
  "eval": function (a) {
  return new Promise(function(c,g){function e(){var d=b.indexOf("\n");if(0<=d){clearTimeout(p);f=p=void 0;var q=b.substr(0,d);try{c(JSON.parse(q))}catch(t){g(q)}b.length>d+1&&h.emit("data",b.substr(d+1))}}var b="";var p=setTimeout(e,
5E3);f=function(d){b+=d;0<=b.indexOf("\n")&&e()};h.write("\u0003\u0010Bluetooth.write(JSON.stringify("+a+")+'\\n')\n").then(function(){})})
}
 }
Error writing color: Error: Function "substr" not found!
> 

Here is the PUCK.js code

var uartService = null;
var writeCharacteristic = null;
var deviceConnected = false;
var deviceSet = null; // Declare device variable in the global scope
var uartService = null; // Declare UART service variable in the global scope
// Import the ble_simple_uart library

function connect() {
  NRF.requestDevice({ timeout: 20000, filters: [{ service: 'CIRCUITPY8d7a'}]}).then(function(device) {
    console.log("Device found");
    return require("ble_uart").connect(device);
  }).then(function(uart) {
    console.log("Got UART Service");
    console.log(uart);
    uartService = uart;
    deviceConnected = true;
    // Listen for data
    uart.on('data', function(data) {
      console.log("Got data: " + data);
    });

    // Listen for disconnection
    uart.on('disconnected', function() {
      console.log("Disconnected");
      deviceConnected = false;
      uartService = null;
      writeCharacteristic = null;
    });

    // Write a color packet to the uart service
    setColor([255, 0, 0]);

  }).catch(function(error) {
    console.log(error);
  });
}

function setColor(value) {
  if (!deviceConnected) {
    console.log("UART service not ready");
    return;
  }

  const packet = new Uint8Array(7);

  // Set the packet type to the color packet type
  packet[0] = 0x03;

  // Set the color values for the red, green, and blue components
  const red = value[0];
  const green = value[1];
  const blue = value[2];

  // Add the color values to the packet
  packet[1] = red;
  packet[2] = green;
  packet[3] = blue;

  // Set the brightness to 100%

  packet[4] = 0xFF;

  // Set the transition time to 0 seconds

  packet[5] = 0x00;

  // Calculate and set the checksum for the packet
  let checksum = 0;
  for (let i = 0; i < 6; i++) {
    checksum += packet[i];
  }
  packet[6] = checksum & 0xFF;

  // Convert the packet to a string and send it over BLE
  uartService.write(packet.buffer).then(function() {
    console.log("Wrote color");
  }
  ).catch(function(error) {
    console.log("Error writing color: " + error);
  });
}

function red() {
  setColor([255, 0, 0]);
}

function green() {
  setColor([0, 255, 0]);
}

function blue() {
  setColor([0, 0, 255]);
}

var SWBtn = require("https://raw.githubusercontent.com/muet/EspruinoDocs/master/modules/SWButton.js");
var mySWBtn = new SWBtn(function(k){
    console.log("BTN1 detected " + k); // log key press pattern
    if (k === "S"  ) { 
      red(); 
      setTimeout(function(){
        void(0);},mySWBtn.p);
    } else if (k === "SS" ) { green(); setTimeout(function(){
      void(0);},mySWBtn.p);
    } else if (k === "SSS" ) { blue(); setTimeout(function(){
      void(0);} ,mySWBtn.p); 
    } else if (k === "L" ) { connect(); setTimeout(function(){
      void(0);} ,mySWBtn.p);
  }});

and here is the ESP32-s2 code

import board
import neopixel
import time
import busio
import digitalio
import adafruit_ble

from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.color_packet import ColorPacket

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_ble.characteristics import Characteristic
from adafruit_ble.uuid import UUID

from adafruit_airlift.esp32 import ESP32

my_char_uuid = UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")

# Create a new characteristic with the custom UUID
my_characteristic = Characteristic( 
    uuid=my_char_uuid,
    properties=(Characteristic.WRITE | Characteristic.READ,)
)

# If you are using an AirLift FeatherWing or AirLift Bitsy Add-On,
# use the pin settings below.
# If you are using an AirLift Breakout, check that these
# choices match the wiring to your microcontroller board,
# or change them as appropriate.
esp32 = ESP32(
    reset=board.D12,
    gpio0=board.D10,
    busy=board.D11,
    chip_select=board.D13,
    tx=board.TX,
    rx=board.RX,
)

adapter = esp32.start_bluetooth()

uart_characteristics = []
uart_characteristics.append(my_characteristic)

ble = BLERadio(adapter)
uart_service = UARTService()
uart_service._characteristics = uart_characteristics

advertisement = ProvideServicesAdvertisement(uart_service)

pixels = neopixel.NeoPixel(board.A1, 12, brightness=0.5)

while True:
    # Advertise when not connected.
    ble.start_advertising(advertisement)
    while not ble.connected:
        pass
    while ble.connected:
        if uart_service.in_waiting:
            packet = Packet.from_stream(uart_service)
            print(packet)
            if isinstance(packet, ColorPacket):
                print(packet.color)
                pixels.fill(packet.color)
                pixels.show()
            else:
                print("Unknown packet type.")
gfwilliams commented 1 year ago

I'm afraid there's not much I can do to help with suggestions on the unstable BLE - I assume it's pretty stable when you're writing code from the PC, so I guess it's something to do with the ESP32 module. It could even be power supply related if you're running an ESP32 and a bunch of neopixels...

But on the substr front - substr exists, but is for Strings. You're using uartService.write(packet.buffer) so you're writing to the UART library with an ArrayBuffer. Normally Espruino would handle stuff like that but the UART library isn't built-in and was only expecting you'd be sending strings.

Using: uartService.write(E.toString(packet.buffer)) instead would probably fix it.

If you have other errors like this please can you ask on the forum first? Otherwise it gets very hard to keep track of things in the bug tracker here

kairos0ne commented 1 year ago

Thanks for the help will raise issues in forum as requested.