Giter Club home page Giter Club logo

Comments (23)

jetannenbaum avatar jetannenbaum commented on August 24, 2024 1

@jonasthewolf I've played with the IC2.init function with my Pico. It is unclear to me exactly how to set up the call to the I2C.init function, since the micropython documentation doesn't match calling the function on the Pico.

A quick print(dir(I2C)) shows that the class supports the function, but I've tried various iterations of I2C.init(...) with no joy.

Unfortunately, I cannot support your request with the hardware I have, since I can't test the functionality.

@sk8board I've merged your pull requests. Any thoughts in the I2C.init function? Perhaps it works differently on the ESP32?

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024 1

@sk8board I realize many of the MicroPython blocks are either incorrect or perhaps just copied from the MicroPython docs. I agree, to be done properly, both the front end block definitions and the back end code need to be rewritten. I'm ok with it, assuming you want to take it on, but I think there is a limited use for it. I wouldn't incorporate the changes into the RP2040 xml files, since the support for some of the functions are limited. I believe pretty strongly that it is better to add direct support for a part than to attempt to use individual MicroPython blocks. After all, if you know that much MicroPython (and low level) code, why not use an IDE like Thonny? However, I'm happy to have you (or someone else) take on the task if you think there is value. The next question would be, where do you stop? Most if not all of the machine library functionality is incorrect (Pin, SPI, ADCWiPy, RTC, etc.).

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024

Hi,

Yup, that seems wrong. I haven't looked at the Python blocks previously, and they may be different, depending on the processor. I only test with the RP2040 processors. I'll take a look and see what I can do. Thanks for supporting BIPES.

from bipes.

jonasthewolf avatar jonasthewolf commented on August 24, 2024

I think it is already a problem to provide the input to the I2C constructor (e.g. specific pins for SDA and SCL).
I have at least failed to do so using blocks.
A fix would be very much appreciated.

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024

Hi,

This issue was raised recently by another person. They offered to fix the code that is generated. I'm waiting to see if that happens before jumping on it. Frankly, I don't recommend using the micropython code blocks, since they haven't been updated since before I started supporting the project. The SPI & I2C display blocks have been updated/tested. Is there a particular display that you want to use that isn't currently supported?

Thanks,

Jim

from bipes.

jonasthewolf avatar jonasthewolf commented on August 24, 2024

Hi @jetannenbaum ,

Thanks for your fast feedback.
Actually, I would like to control an Adafruit color sensor and a motor driver feather board.
There are however multiple I2C on the Feather Huzzah ESP8622 board.
I at least thought that I needed to provide the correct pins.

Best regards,

Jonas

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024

Hi Jonas,

Hmmm... I don't support the ESP8622 board (I don't have one). I can patch the code, but I can't test it. I do have a couple color sensors; support is already added for the GY-33. I also have the TCS34725, which I could add support for.

Is the motor driver board a PCA9685? I can add support for that as well, if that is what you have.

Let me know. I have some time Sunday and can add support for any hardware that I already own. You would have to test though.

Jim

from bipes.

jonasthewolf avatar jonasthewolf commented on August 24, 2024

Wow, thanks.
However, I would be absolutely fine to do all the I2C commands on my own.
To be able to do that, it would be necessary to be able to configure the pin parameters for the I2C.init block.
Here is the hardware I have:

from bipes.

sk8board avatar sk8board commented on August 24, 2024

This issue was raised recently by another person. They offered to fix the code that is generated. I'm waiting to see if that happens before jumping on it. Frankly, I don't recommend using the micropython code blocks, since they haven't been updated since before I started supporting the project.

@jetannenbaum , Are you referring to me? If so, I apologize for the misunderstanding. I thought you were not interested in having the micropython code blocks fixed, so I have not attempted to repair these blocks.

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024

@sk8board: perhaps I misunderstood. I thought you mentioned doing a pull request after fixing the code locally. No biggie. I can make the changes and push the updates.

@jonasthewolf: sorry, I don't have any of that hardware. As mentioned above, I'll take a look into fixing the I2C & SPI code. I'll test it on the RP2040 board. Since I'm changing the underlying code generation (generator_stubs.js) code, you'll need to refresh your browser, but will not see any other changes to the block code. I think you'll be sending a bunch of commands through the I2C blocks, and it might be simpler to download the libraries and write the micropython code. The motor driver board appears to be based on the PCA9685. I have the board and a library for that and can add it to BIPES. The library is available here: https://github.com/adafruit/micropython-adafruit-pca9685 I don't have anything that will support the APDS9960. The library for the APDS9960 board is available here: https://github.com/rlangoy/uPy_APDS9960/

Please let me know what you decide. I'm willing to make the changes to the I2C, SPI, and/or add support for the PCA9685 board, but there is still work to be done (and a part to purchase) to add BIPES support for the APDS9960.

from bipes.

jonasthewolf avatar jonasthewolf commented on August 24, 2024

Hi, @jetannenbaum

I guess the most generic thing that would help the most people is, adding the pin configuration to the I2C init block.

That would be really great.

from bipes.

sk8board avatar sk8board commented on August 24, 2024

@jetannenbaum I have submitted a couple of pull requests to you (not related to this issue). Please let me know if you need any help. I have a Pico and an ESP32 with various IO hardware.

from bipes.

sk8board avatar sk8board commented on August 24, 2024

@jetannenbaum I have reviewed the file below and have determined the Micropython > I2C code blocks were never developed. I believe most (if not all) of the Micropython blocks are placeholders for future development.

More than the file below would need to be modified. Are you OK with changes for this scope of work?

image

from bipes.

sk8board avatar sk8board commented on August 24, 2024

@jetannenbaum I went through the learning curve to create the I2C.init block. You are correct, it is much work to take on. I do not see myself completing I2C anytime soon...

After all, if you know that much MicroPython (and low level) code, why not use an IDE like Thonny?

After watching my son transition from Scratch to learn MicroPython, he was struggling with learning both MicroPython and nuances of microcontrollers at the same time. Learning both MicroPython and microcontrollers was too much. Using block coding at a low level helps to learn microcontrollers before learning MicroPython. Using these blocks, will naturally help with learning MicroPython. Therefore, I believe there is much value.

In general, I believe you are correct that there is more value in creating code blocks for specific hardware. I also believe there is an exception to that rule which is the Adafruit product line. Adafruit relies heavily on I2C for much of their I/O. I suspect that making code blocks for each of their products is more work than making generic I2C blocks.

https://www.adafruit.com/category/1005

from bipes.

sk8board avatar sk8board commented on August 24, 2024

I think you'll be sending a bunch of commands through the I2C blocks, and it might be simpler to download the libraries and write the micropython code.

@jetannenbaum I am not sure what you mean. I do not understand how he would use downloaded libraries with BIPES. Is there a way for the user to add a library to BIPES? Would you be able to elaborate to help me understand?

from bipes.

QuirkyCort avatar QuirkyCort commented on August 24, 2024

If you want to add I2C blocks to BIPES, you can feel free to copy the implementation from https://github.com/QuirkyCort/IoTy

The generated code are tested on the ESP32. Should work on the ESP8266 (...not tested, might need to use the version with pins specified as the ESP8266 do not have hardware default for the I2C pins). And should work on the Pico (...some testing a long time back, but not as thorough as the ESP32).

As for the issue with I2C.init(), I'm not sure if you need that at all. You can just perform initialization in the constructor.

@sk8board A lot of devices uses I2C, but reading and controlling them using I2C blocks is generally not trivial. I think that reading and controlling I2C devices using generic I2C commands is a good learning exercise in reading datasheets and understanding how I2C works, but that's something I only do with older students (16-18yo) and even then, most of them struggles with it. Since many of the Adafruit products should already have micropython libraries, it would be easier to switch to writing your code in micropython instead of blocks, and use those libraries.

from bipes.

sk8board avatar sk8board commented on August 24, 2024

@QuirkyCort Thank you for your willingness to help. I looked at your code and noticed most of your I2C code is in .json and .py format. Most of the code for this change in BIPES is .js and .xml.

Also, the Blockly code for BIPES seems to be an old version of Blockly that is not compatible with the latest Blockly dev tool. This reduces efficiency of using the Blockly dev tool.

https://blockly-demo.appspot.com/static/demos/blockfactory/index.html

Here is an example to support changes to the I2C.init block.

block_definitions.js

/* Original block code to be removed
Blockly.Blocks["machine.I2C_I2C.init"] = {
  init: function() {
  this.appendValueInput("pIn")
        .appendField(" I2C.init");
        this.setColour(0);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
 this.setTooltip(" ");
 this.setHelpUrl("https://docs.micropython.org/en/latest/library/machine.I2C.html");
  }
};

New block code*/

Blockly.Blocks["machine.I2C_I2C.init"] = {
  init: function() {
    this.appendDummyInput()
        .appendField("I2C Init");
    this.appendValueInput("I2C_ID")
        .setCheck("Number")
        .setAlign(Blockly.ALIGN_RIGHT)
        .appendField("I2C ID");
    this.appendValueInput("sda_pin")
        .setCheck("Number")
        .setAlign(Blockly.ALIGN_RIGHT)
        .appendField("SDA Pin");
    this.appendValueInput("scl_pin")
        .setCheck("Number")
        .setAlign(Blockly.ALIGN_RIGHT)
        .appendField("SCL Pin");
    this.appendValueInput("I2C_frequency")
        .setCheck("Number")
        .setAlign(Blockly.ALIGN_RIGHT)
        .appendField("I2C Frequency");
    this.setInputsInline(false);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(0);
 this.setTooltip("");
 this.setHelpUrl("https://docs.micropython.org/en/latest/library/machine.I2C.html#machine-i2c");
  }
};

generator_stubs.js

/*  Original block code to be removed
Blockly.Python["machine.I2C_I2C.init"] = function(block) {
		var value_pIn = Blockly.Python.valueToCode(block, 'pIn', Blockly.Python.ORDER_ATOMIC);
	var code = "machine.I2C.I2C.init(" + value_pIn + ")\n"; 
	return code;
};

New block code */

Blockly.Python["machine.I2C_I2C.init"] = function(block) {
	var I2C_ID = Blockly.Python.valueToCode(block, 'I2C_ID', Blockly.Python.ORDER_ATOMIC);
	var sda_pin = Blockly.Python.valueToCode(block, 'sda_pin', Blockly.Python.ORDER_ATOMIC);
	var scl_pin = Blockly.Python.valueToCode(block, 'scl_pin', Blockly.Python.ORDER_ATOMIC);
	var I2C_frequency = Blockly.Python.valueToCode(block, 'I2C_frequency', Blockly.Python.ORDER_ATOMIC);
	Blockly.Python.definitions_['import_I2C_Pin'] = 'from machine import I2C, Pin';
	var code = `
i2c_pins = I2C(` + I2C_ID + `, scl=Pin(` + scl_pin + `), sda=Pin(` + sda_pin + `), freq=` + I2C_frequency + `)
	`;
	return code;
  };

rpi_pico.xml

      <category name="I2C">
      <label text="I2C"></label>
<block type="machine.I2C_I2C.init">
<!-- Start of new code -->
  <value name="I2C_ID">
    <shadow type="math_number">
      <field name="NUM">0</field>
    </shadow>
  </value>
  <value name="scl_pin">
    <shadow type="math_number">
      <field name="NUM">1</field>
    </shadow>
  </value>
  <value name="sda_pin">
    <shadow type="math_number">
      <field name="NUM">0</field>
    </shadow>
  </value>
  <value name="I2C_frequency">
    <shadow type="math_number">
      <field name="NUM">400000</field>
    </shadow>
  </value>
<!-- End of new code -->
</block>
<block type="machine.I2C_I2C.deinit">
</block>
<block type="machine.I2C_I2C.scan">
</block>
<block type="machine.I2C_I2C.start">
</block>
<block type="machine.I2C_I2C.stop">
</block>
<block type="machine.I2C_I2C.readinto">
</block>
<block type="machine.I2C_I2C.write">
</block>
<block type="machine.I2C_I2C.readfrom">
</block>
<block type="machine.I2C_I2C.readfrom_into">
</block>
<block type="machine.I2C_I2C.writeto">
</block>
<block type="machine.I2C_I2C.writevto">
</block>
<block type="machine.I2C_I2C.readfrom_mem">
</block>
<block type="machine.I2C_I2C.readfrom_mem_into">
</block>
<block type="machine.I2C_I2C.writeto_mem">
</block>

      </category>

esp32.xml

      <category name="I2C">
      <label text="I2C"></label>
<block type="machine.I2C_I2C.init">
<!-- Start of new code -->
  <value name="I2C_ID">
    <shadow type="math_number">
      <field name="NUM">0</field>
    </shadow>
  </value>
  <value name="scl_pin">
    <shadow type="math_number">
      <field name="NUM">22</field>
    </shadow>
  </value>
  <value name="sda_pin">
    <shadow type="math_number">
      <field name="NUM">21</field>
    </shadow>
  </value>
  <value name="I2C_frequency">
    <shadow type="math_number">
      <field name="NUM">400000</field>
    </shadow>
  </value>
<!-- End of new code -->
</block>
<block type="machine.I2C_I2C.deinit">
</block>
<block type="machine.I2C_I2C.scan">
</block>
<block type="machine.I2C_I2C.start">
</block>
<block type="machine.I2C_I2C.stop">
</block>
<block type="machine.I2C_I2C.readinto">
</block>
<block type="machine.I2C_I2C.write">
</block>
<block type="machine.I2C_I2C.readfrom">
</block>
<block type="machine.I2C_I2C.readfrom_into">
</block>
<block type="machine.I2C_I2C.writeto">
</block>
<block type="machine.I2C_I2C.writevto">
</block>
<block type="machine.I2C_I2C.readfrom_mem">
</block>
<block type="machine.I2C_I2C.readfrom_mem_into">
</block>
<block type="machine.I2C_I2C.writeto_mem">
</block>

      </category>

image

image

var value_pin = Blockly.Python.valueToCode(block, 'pin', Blockly.Python.ORDER_ATOMIC);

from bipes.

QuirkyCort avatar QuirkyCort commented on August 24, 2024

In Blockly, blocks definition can be written in js, json, or xml. In IoTy, I use (mostly) json, while BIPES seems to have it in js. The blocks definition are fairly trivial to write, so I'm not expecting BIPES to copy that from IoTy.

The toolbox definition is written in xml for both IoTy and BIPES, but that's again fairly trivial, so not expecting BIPES to copy from IoTy.

When I suggested taking from IoTy, I was referring to the code generator and the design of the blocks.

For the code generator, there are a lot of nuances there that you need to watch out for. I'm not fully confident in the robustness of my own code generator, but it is ahead of BIPES in at least some areas.

For blocks design, it is rather more subjective, but you might find it informative to see how IoTy designed it's I2C blocks.
To give an example...

In BIPES, the I2C blocks are a largely a 1-to-1 mapping to the I2C methods, so you have a readinto method. But that requires an object with a buffer protocol, and there are no blocks in BIPES to create such an object. You'll also need some way to unpack the bytes into a usable value (...int, float, etc), but there are again no blocks in BIPES to do so. IoTy works around this by performing the reading and unpacking in a single block.

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024

There is lots to unpack here, so I'll jump in with a brief history lesson then add commentary. BIPES was written by a team under the leadership of @rafaelaroca while he was a professor at the Federal University of Sao Carlos in Brazil. A few years back I was working with a friend as he transitioned from using Arduino microprocessors to Raspberry Pi Picos. I wanted to build / find code that would allow us to use blocks to program the board (I had just bought the makeblock and was intrigued by their programming solution). I found BIPES and started to run the offline (local) version. Rafael was still involved at that point and was nice enough to allow me to build a version of BIPES on the server that was focused on the RP2040 boards. As noted, I support that version to this day. I have not updated to the latest Blockly implementation (My mantra has always been, it works as is, don't update until it doesn't), nor have I added blocks in json, since the original implementation was in javascript. I'd rather build on what is there then start adding different frameworks.

Enough history. Fast forward to today's / yesterday's discussion. We could add the class instantiation to BIPES for the init(...) method. However;, the code wouldn't reflect the name of the block. Seems disingenuous. Obviously, you can do whatever you wish locally, but I would have a hard time accepting that into the base project without a lot of discussion. As @QuirkyCort points out, that still doesn't solve @jonasthewolf 's problem, since there is a lot of code that is needed to support the devices that @jonasthewolf mentioned. Some of that code isn't easily supported in BIPES. And there is a lot to learn from the data sheets before getting anything to work, pushing byte codes. There are Micro Python libraries that support the boards that @jonasthewolf has. They can be added to BIPES, either locally (take a look at how the pylibsBlobs differ from the pylibs files) or on the server (I still use the pylibsBlobs library files on the server, since that makes it easier to support both the offline and server versions of the RP2040 code base).

I think we are a bit off topic at this point and would support closing down this issue with a "yup, it is a problem in BIPES, not going to fix it" note. It is left to the interested person if they want to update the code locally.

@sk8board, @QuirkyCort , @jonasthewolf , @rafaelaroca: Thoughts?

Thanks for the discussion,

Jim

from bipes.

jonasthewolf avatar jonasthewolf commented on August 24, 2024

@jetannenbaum thanks for already putting so much effort into my request.

I initially thought I just missed something completely.
I now understood the "simple thing" I was looking for is not implemented, and not that easy to implement.

I would go for writing the low-level stuff for my hardware in Python, and show my son how to use those functions in the Blockly representation.

Thanks again!

from bipes.

sk8board avatar sk8board commented on August 24, 2024

@jetannenbaum agreed. Thank you for your support!

from bipes.

QuirkyCort avatar QuirkyCort commented on August 24, 2024

@jonasthewolf If you're open to using an ESP-32 instead, IoTy supports programming both the APDS9660 and the PCA9685 (...the motor driver board that you linked to) with blocks. IoTy isn't a one-to-one replacement for BIPES, but you may find it to be an acceptable alternative for your son.

@jetannenbaum Perhaps the non-working blocks should be removed from the toolbox. Would avoid a lot of confusion.

from bipes.

jetannenbaum avatar jetannenbaum commented on August 24, 2024

@QuirkyCort: I haven't explored all of BIPES, since I don't use all of the functions and I don't have all of the hardware. That leaves me with the dilemma of possibly removing functions that work (and might be of use). I could remove all of the boards that I don't support from the offline and RP2040 online code, but that doesn't seem right either.

from bipes.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.