microsoft / pxt-chibitronics

Chibitronics Love To Code board editor with Microsoft MakeCode
https://makecode.chibitronics.com
Other
23 stars 15 forks source link

New blocks request for sensing #95

Closed jieq closed 6 years ago

jieq commented 7 years ago

Natalie and I are wondering if it's possible to add 3 new c-shaped blocks (like the forever loop) to the sensing category that respond to changes in voltage to an input pin:

Basically to make it easier to work with switches (rather than needing to build out your own with an if statement block and variable).

Also, an additional block that sets the default to be ON (basically a way to turn on the internal pull-up resistor). So something like "set normally ON" (though I'm not sure that's the best wording...?)

samelhusseini commented 7 years ago

We have previously wanted to have Events, and there's quite a few opportunities for this to make programming much easier here.

@xobs and @mmoskal what do we need to do to get events going in this target. I know the forever block uses it's own thread.

For the normally on block, perhaps just "set default to ON/OFF"

pelikhan commented 7 years ago

In CODAL we use a event queue, fibers and timer to handle events and run user code outside of interrupts. What kind of support is available in the LTC runtime for events today?

We also have a “pin on pulsed low/high” event that does just this (under a more scary name).

mmoskal commented 7 years ago

@xobs - assuming you have a function like this in your kernel:

void registerMyEvent(void (*)(uint32_t) fn, uint32_t userdata);

you can write the following in the C++ of PXT code:

//% ... stuff ...
void onMyEvent(Action a) {
  if (a != 0)
     registerMyEvent(runAction0, a);
}
mmoskal commented 7 years ago

PXT in other targets behaves as follows:

pelikhan commented 7 years ago

We also have a button abstraction over a pin to handle this like “click”, “hold”, “up”, “down”.

Are you planning to use events In the book? They are typically more intuitive to use than a forever loop with lots of if statements.

Get Outlook for iOShttps://aka.ms/o0ukef


From: Michał Moskal notifications@github.com Sent: Thursday, October 5, 2017 7:10:02 AM To: Microsoft/pxt-chibitronics Cc: Peli de Halleux; Comment Subject: Re: [Microsoft/pxt-chibitronics] New blocks request for sensing (#95)

PXT in other targets behaves as follows:

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fpxt-chibitronics%2Fissues%2F95%23issuecomment-334476564&data=02%7C01%7Cjhalleux%40microsoft.com%7C8f0dcd2a9f3c43ecd5eb08d50bfac600%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636428094051373350&sdata=hLGazf1Hq%2BH9WihfYfK6%2B3L9ODXKZtlbICGK3h28Tyo%3D&reserved=0, or mute the threadhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAD-4KTAEAfsqiHqo47fftlIlelKs-p6Cks5spOM6gaJpZM4Pugjg&data=02%7C01%7Cjhalleux%40microsoft.com%7C8f0dcd2a9f3c43ecd5eb08d50bfac600%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636428094051373350&sdata=RRGxlPGQd4SkbqZFcOD9F%2FT6pnrgixctjBA2uyl2ti8%3D&reserved=0.

xobs commented 7 years ago

The ROM-based routines are really basic. They're roughly based on Arduino, so basically all you can do is redirect OS-level interrupts to user code.

What sort of events are you looking for? GPIO inputs, or something more exotic? The list of interrupts we can hook is in Arduino.h:

#define PMC_IRQ           6
#define I2C0_IRQ          8
#define I2C_IRQ           9
#define SPI_IRQ           10
#define SERIAL_IRQ        12
#define ADC_IRQ           15
#define PWM0_IRQ          17
#define PWM1_IRQ          18
#define LPTMR_IRQ         28
#define PORTA_IRQ         30
#define PORTB_IRQ         31

Likely we will need to come up with a simple interrupt-dispatch routine that hooks both PORTA and PORTB interrupts, then hands it off to the appropriate callback. Basically implementing the registerMyEvent() function recommended by @mmoskal .

pelikhan commented 7 years ago

In CODAL (micro:bit runtime and others), user code does not run within the interrupt context. Instead, an event is pushed into an event bus that gets processed from a timer outside of interrupts. This is required because the BLE stack is very picky about interrupt and having a blocking user procedure in that context would have catastrophinc results :)

As far as events, they are tied to sensors available on board. We tend to provide events which surface a higher level abstraction concept: e.g. a button click event on top of a pin, or a shake gesture event on top of an accelerometer.

xobs commented 6 years ago

I've pushed the sensing branch which handles "events" in software. It spawns a thread and polls at 10ms intervals. onPress, onRelease, and onChange are supported, and we could make more.

An unlimited number of events can be attached, including multiple events to a single pin. This means you can do the following, and pins 3, 4, and 5 will toggle based on pressing pin 0:

input.onPinPressed(DigitalPin.D0, function () {
    touch_counter_press = touch_counter_press + 1
    pins.digitalWrite(DigitalPin.D5, touch_counter_press & 1)
})
input.onPinReleased(DigitalPin.D0, function () {
    touch_counter_release = touch_counter_release + 1
    pins.digitalWrite(DigitalPin.D4, touch_counter_release & 1)
})
input.onPinChanged(DigitalPin.D0, function () {
    touch_counter_change = touch_counter_change + 1
    pins.digitalWrite(DigitalPin.D3, touch_counter_change & 1)
})
let flash_counter = 0
let touch_counter_press = 0
let touch_counter_release = 0
let touch_counter_change = 0
loops.forever(function () {
    flash_counter = flash_counter + 1
    loops.pause(100)
    pins.digitalWrite(DigitalPin.D1, flash_counter & 1)
})

There is no simulator support, as I'm not sure how to do that.

bunnie commented 6 years ago

Sean, thanks for pushing this. Microsoft team -- this one slipped through the cracks when I was reviewing critical issues. Apparently the tech editor who is doing the translation of Love to Code Volume 1 to Make Code has flagged that the event blocks would make the chapter much better and in-line with the other systems that use Make Code.

Would it be possible for us to focus a little time on getting this integrated into the live Beta at least so we can write chapter 3 using the event blocks?

samelhusseini commented 6 years ago

Great stuff @xobs. I have a few questions for you here:

samelhusseini commented 6 years ago

I added simulator support and pushed to your branch.

xobs commented 6 years ago

What might be a good idea is to expose input::registerEvent() to typescript, and do the actual blocks in typescript code. I'm not sure how to do that.

Also, I'm not sure how to make it so that the first parameter is a DigitalPin. As-is, the first parameter is usually 0-5, whereas DigitalPin::D0 is 0xa0 and DigitalPin::D5 is 0xa5. As a result there's a lot of gymnastics to normalize the pin.

mmoskal commented 6 years ago

You might also want to set the pull - I guess you will normally want to have users connect ground to the pin, so "Active" is low and you need a pull up.

I assume the chip doesn't have hardware cap-touch?

xobs commented 6 years ago

It doesn't have hardware captouch.

There's a schmitt trigger on the input which lets users touch +3.3V and get it to work. I believe @bunnie can comment on the hardware, but it's designed to work like you'd expect with the input floating.

bunnie commented 6 years ago

It's resistive touch and we have 22M resistors to ground on the inputs already. The prescribed method to activate a touch input is to touch the +3.3V line and the desired pin to activate.

However, to be clear, Jie's request is in the construction of "classic" switches. Her construction still conforms to the standard of relying upon the weak 22M pull-down to bring the input to ground, and closing the circuit to +3V, so in this case you would not want to set an input pull-up because that would override the pull-down and cause the examples in the book to stop working.

samelhusseini commented 6 years ago

Okay cool. I moved it to a single block, no need to go to TS for that. I think now we just need to figure out terminology, and we should be all set. @pelikhan @jieq @Jaqster thoughts on what the different events should be? In other targets we have:

I think it makes more sense to use "Pressed", "Released" only. For Up / Down.

pelikhan commented 6 years ago

Pressed, Released, Changed. Click is somewhat weird in the context of paper circuits.

jieq commented 6 years ago

Hello!

Natalie and I discussed and we also really like the simplicity of "Pressed, Released and Changed."

We also had 3 requests for potential updates:

  1. "when" instead of "on" in the event block so that we don't see the word appear twice, which is grammatically confusing. That is, "turn a pin ON" versus "on the event occurring"

  2. In the logic block, have "is [D0] HIGH?" and "is D0 LOW" with a dropdown menu for the two options, instead of "is D0 on" to communicate the state of a pin. This takes away the ambiguity of the word "on" (turning it on versus sensing a HIGH voltage). HIGH and LOW are still visually descriptive as they still match the brightness of the indicator LED.

  3. In the trigger block, add "HIGH" and "LOW" as options in the dropdown menu, to enable more advanced options? The idea is that if people later want to craft a switch that is normally on (HIGH), and connects to GND (LOW) when pressed, then the user won't have to navigate reversing the wording of the block in their heads (since in this case, the pin will go LOW when pressed and HIGH when not pressed).

Thanks a bunch and we're excited to see these new blocks! :)

samelhusseini commented 6 years ago

Hey Jie. I think I get the first and second requests, and this is what they would look like:

screen shot 2017-11-02 at 12 19 54 am

I don't quite understand the third one. What do you mean by the trigger block? Is that the turn D0 ON block?

nataliefreed commented 6 years ago

I think Jie is referring to the new "when pin is " block. We talked about the idea of adding HIGH and LOW to the bottom of the dropdown list in addition to pressed, released, changed. With a switch wired up the way the book teaches it (pressed goes high, released goes low), pressed and released make sense and are nice and easy to understand for beginners. But if someone wants to work in an advanced way by turning on the internal pull-up resistors, or in some other way creates a switch that goes low when pressed, HIGH/LOW labels are more versatile.

samelhusseini commented 6 years ago

Oh cool. Yeah we can add two more options that do basically the same thing to the list, to make it clearer for those using HIGH / LOW.

samelhusseini commented 6 years ago
screen shot 2017-11-02 at 3 31 56 pm
samelhusseini commented 6 years ago

Fixed, in /beta

nataliefreed commented 6 years ago

I'm having trouble with the new "is [D0] [HIGH/LOW]" block (previously "is [D0] ON?"). This code https://makecode.com/_6L97xff1YPdA works fine on the Chibi Chip with the old block in the main editor, but if I use the beta editor to upload to the Chibi Chip, the LED on pin D1 never turns on. The simulator version does appear to work on both (although, perhaps as a separate issue, the simulator seems to "stick" the button press until you toggle it off). Thank you! switch code screenshot

samelhusseini commented 6 years ago

Hey @nataliefreed I think you might be right. The previous block "is D0 ON?" checked if the pulse was greater than 0 for High, and 0 for Low. However the new block takes in an input (High / Low) and checks whether the pulse is equal to the values of the input High / Low. It's possible the pulse Value for high is not 1. @xobs is it some other value? or is it a range?

samelhusseini commented 6 years ago

Fix here: https://github.com/Microsoft/pxt-chibitronics/pull/136

samelhusseini commented 6 years ago

This should be fixed in beta.