#circuitpython-dev
1 messages ยท Page 132 of 1
i think for libs yah, lets put the troubleshoting parts in troubleshooting, i did solve a bunch of it by putting those special files on the trinket/gemma when they ship
and then the rest about libs, should that have a separate page? Or go in the advanced users page? and if separate, where should we put it. I wanted to keep it out of the main workflow of the overall guide because you can't simply load the entire thing onto Trinket and Gemma so we'd be getting into board-specific instructions which I basically avoided through the entire thing.
hah had four thoughts while trying to type this out, and then came to: I think it needs to be right before what's next because what's next sends them to the board-specific guides. some of which have examples needing libraries.
on creating and editing you may want to say any plain text editor will be fine to rule out word
i think libraries can actually go after the 'boards overview' page
ok keen
one library that will work on all devices is simpleio
so you can use that to 're-write' blinky
but lets you demonstrate "hey you got an import error, lets fix it"
I'm not even sure I know how to rewrite blinky with simpleio
ah
๐
So at that point, though, are we just dragging simpleio over in the guide? Or explaining that it's different for trinket and gemma
and having them drag the entire lib folder for the boards where it will fit, and specify the little ones
i think you can start by showing just adding that library
ok
so it works on eveything
keen
and THEN say "OK if you have an Express board" just grab the whole thing
but make the "lib" folder either way
"it won't actually eject" leads my to picturing usb keys being spit out of a computer
lol
weirdest weapon ever
newer zip files will also have lib folders in them even when they are for a single library
good to know.
kat, maybe also rename 'whats next?' to be called 'CircuitPython Boards' or similar?
I'm thinking still use the bundle for the libs example
๐ค
what's next made sense when it was the last page
I changed a couple things to suggest the drive is corrupted instead of the board
that sounds good
kat, ya! either way point them to the whole bundle, using the wildcard URL
CircuitPython Hardware for that page name?
sounds good to me ๐
I use boards through the whole thing though
I think boards might make more sense
dunno
is it ok if I tweak some wording?
Ok so: add cp libs, for advanced user pages. rename what's next. add the rest of the libs page to troubleshooting.
@slender iron yeah for sure
I want to clarify that time.sleep doesn't know anything about the led
limor already made changes, this kind of group work is great
oh I thought I worded it like that... yeah definitely clarify that
oh wait I had it like that and then kept trying to simplify it. I remember now
but yes definitely clarify that one.
@meager fog did you specifically see something I missed from the serial repl page that's already there, or did were you just having me make sure I covered it all
i dont think you missed anything but i also didnt do a thorough check ๐
maybe just skim thru, see if we missed anything (i dont think we did?)
ok, np, I just wanted to make sure
yeah for sure. I'll do that once I have the rest of it finished up
@idle owl I rephrased it as time.sleep() tells CircuitPython to pause running code
nice
@idle owl I really like the NameError example. perhaps reiterate you can google for other errors because its just like python?
I added another screenshot to the REPL page, and a sentence about potentially needing to press ctrl+c multiple times but that sentence was the only thing missing from the current page.
@slender iron sounds good
@idle owl it looks really really good
Ready to re-review. Squash merge if you like due to multiple commits.
@slender iron thank you so much!
we should add featured products too ๐
I was going to ask about that
I'd just add the five mentioned in it
that was what I was thinking too
And all this wonderful development without a single whiteboard. Amazing.
Sorry! just kibitzing again. Love the conversation. Brings back memories.
maybe put CPX at the top? 
@tidal kiln think so? I was going to put them as trinket-gemma-cpx-feather-metro as it seemed like the most likely order you'd get them, but the featured ones are meant for you to get them, not that you already have them. Yeah I think CPX should go first.
is this for right hand side? or on a guide page?
right hand side list thing
anything's fine, only suggesting CPX as lots of people getting them soon-ish to now-ish
true, I think it's the best getting started board, so I like it being first on this guide. The guide itself is board-agnostic.
yep, that too - best starter board
@idle owl more text editor info: sublime and vi do fsync, so they are "safe" editors. nano does not do fsync.
@tulip sleet good to know. Sublime still scares me ๐
I only recently moved from Atom to PyCharm.
dunno about Pycharm, but i can test that too if you want
That would be amazing. It's a more complicated editor, not great for beginners I don't think, but it's not nearly as intimidating as Sublime. The community edition of it is free.
i never got started on sublime because it cost money, and it's TOO DARK in there. I like light themes ('course I could change that)
@timber lion Do you have time to answer a few questions about tap detection in lis3dh?
I tried sublime but atom has borrowed heavily from it so it felt very similar
PyCharm has a learning curve when working with CircuitPython because of the workflow. I still run into issues sometimes. But I'm slowly figuring out how I have to use it to make it work with mutliple boards plugged in and so on. For a while it was incredibly frustrating, but I worked hard to give it a chance.
@slender iron just PR'd ds18x20 and onewire, did a few significant last minute tweaks:
- allow specifying start, end for readinto and write (faux slicing)
- above let me get rid of single byte buffer
- added resolution setting/reading for ds18x20
- had to refactor the "wait for convert" stuff into convert_temp, it wasn't working like it was
thanks @tidal kiln will look later
@slender iron also, ads1x15 made it in latest auto bundle, so that's fixed. ๐
@meager fog got me into a wear leveling rabbit hole I want to explore for a little bit
np. whenevs.
oh hey @idle owl yeah totally i'm around
@timber lion Great! at the moment I'm trying to write a simple program that detects taps - trying to understand it and sort if so I can add it to the cpx API. I have notes from ages ago where I figured out the binary for each axis +/- (so -x, +x etc separately). the code right now is super kludgey with the stuff from my notes and some things from your fidget spinner code. If I just do read_click and set_click it responds to shake, movement, tapping, everything, even with a higher threshold. So I'm thnking the magic lies in the FIFO buffer and streaming stuff you have in the spinner code, but I don't get how to adapt it for all axes. I'm not great with data-sheets although this is the one I've read most (that doesn't mean much), and I only have an academic understanding of interrupts.
So.... long story short, I'm trying to figure out tap detection, allow for specifying double/single click, using one axis, or any combination thereof.
And I need some help understanding what's going on in the code or the driver... and I'm not really sure what questions to even be asking. So apologies if this sounds like I'm asking the vaguest thing ever here
oh gotcha, actually it might easier to start from a simpler example
I agree completely
check this one out: https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH/blob/master/examples/click.py
so it's using a feature built in to the LIS3DH for click/tap detection
which is kinda cool to read about in their app note
don't have to fully grok all the details, good to just skim
and then if you want you can see exactly what registers are used for click detection in the datasheet
those are pretty technical and dry, it's just a raw reference of the registers
but super handy when you see weird hex values and wonder what they mean
the app note is good to get the big picture and how ST wants you to use the deivce
then the DS helps show the actual bits to set
but start with just the simple example from the library above too
Ok
what it's doing is turning on click detection for all 3 axes, then specifying either single or double click detection.. both those changes are just setting special values in the CLICK_CFG and CLICK_SRC registers
then to see if a click occured the chip will set a special bit in a register
Ok I have it running, but it's doing the same thing as I was running into before trying to adapt the more complicated code
if I even move the board, it registers a click or two
so the library checks that bit in the functions and if it's set it can return a true/false for click or no click detected (and even type of click, single or double)
ah yeah so click detection doesn't really know the difference between a sharp movement and a tap
it's all the same to it, from the app note it talks about how it looks for a sharp increase in acceleration and if it falls back down in a certain window of time
so you can tweak the thesholds a bit and increase how sharp of an impulse or spike it needs to see
and even the window of time for it to fall back down a bit
ok!
so yeah it might hard to have it not detect sharply moving the board vs. a click
ok
but you might be able to play around with the time window and threshold parameters
I thought I was missing something and that's why it wasn't working right
So there's no point in trying to include the write_byte_register stuff from your spinner code?
ah that stuff is just a little wrapper to make setting register values easier
it's already in the lis3dh lib though, let's see what i called it
because as it is it calls a protected class member, so I wasn't sure if there was a better way to do it. or whether it was even needed for tap detection.
ah yeah similar names but with underscores: https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH/blob/master/adafruit_lis3dh.py#L236-L249
ok yeah
ohh gotcha, yeah so that's in the example it wanted to change the click and other registers to specific values
the library didn't expose public functions for it since it's kind of complicated and lesser used stuff
but since i knew how the library worked i just reached in and called the 'private' function rather than doing all the I2C calls etc myself
it's not ideal to do it that way but a lot simpler than adding extra stuff to the lib right now
but yeah ultimately that stuff is just adjust the click detection to only look at one axis
vs. for more general click/tap you probably want to look at all 3
the spinner only wanted to tell when you hit a specific side of the board
I was thinking of including individual axes, maybe that's a bit much for the API?
but for a person tapping the board/chip it might come from any direction
right
yeah i'd say keep it simple to start.. go for all 3
if you see people asking or good use cases come up for just one or two axes then might make sense to add later
yep totally.. one big thing i come back to a lot.. YAGNI
You Ain't Gonna Need It
๐
nice philosophy from the agile world
๐
it's easy to jump in and want to add every feature.. but ultimately it's just extra code and complexity that has a cost to write and maintain
so start simple and add is a good way to approach stuff
and memory usage.
yeah that's how I came to a lot of it. Added things later.
ok, thank you! I might ping you again but I'm getting it much more than I was. much better place to start
yep no problem!
Guard Against Feature Creep
If it can, it will.
KISS, Keep It Simple Sir.
Software philosophies one should always abide by. Good work people.
...just kibitzing... ><>
yeah when i was younger and more inexperienced i took great pleasure in writing a lot of code.. the more the better
now i take pleasure in writing the least amount ๐
i treat it like a dangerous substance
ain't it the truth. We have reuse for a reason. Right?
Gotta love inheritence.
Computers are funny people.
They rarely will do exactly what you want them to do yet they always do exactly what you tell them to do. ๐
@idle owl PyCharm syncs after write if "safe write" is turned on in Settings->System Settings->Synchronization. Tested on Windows briefly. Seems to do the right thing.
"Safe Write" is on by default (out of the box).
@tulip sleet Oh nice! Thank you!
Hmm so double click detects single as well.
Is this even doing anything in CP? time.sleep(0.05)
I'm on 2.x
I seem to remember there being something about super tiny time.sleep values
anything above 0.001 seems to do at least some amount of sleeping
ok thank you
@slender iron the onewire PR is failing travis. looks like it's related to pylint? i tried some stuff, but none of it worked. i'd like to know / learn what's up there. (when you get to it)
@tidal kiln I might be able to help.
Ok here are your errors: ```W:136,12: Unused variable 'i' (unused-variable)
W:200,16: Unused variable 'bit' (unused-variable)
R:190, 4: Method could be a function (no-self-use)```
The last one I needed to use a @classmethod decorator to make it happy. The other two might need to be disabled, depends on where they are in the code.
Link me to the code please
yah, i linted locally and saw those. i don't think they're worthfixing.
ok, then you'll have to do the # pylint: disable=error-name thing at those points in your code
Fairly certain it's the bit in parens that is the error name
so # pylint: disable=unused-variable etc
is travis setup to require a 100% pass from pylint?
Yes
You did pretty good!
Well it's not kludging it
it's showing that we chose to not follow the linter so there's consistency across the board
It's not bad form to disable pylint, it's simply a form
At least that's how I see it
that makes sense. i was thinking it'd be nice to dumb it down at the travis level.
Means we'll have inconsistencies later though with new people coming in. We all know how we're doing things, but we won't be it for long.
but having the flag in code does what you said "yah, we know pylint doesn't like this, but....meh"
yep exactly
or we know pylint doesn't like this but it works better for what we're doing, etc.
The errors go at the point in the code where the error occurred like so: python @property def touch_A1(self): # pylint: disable=invalid-name
Similar for disabling entire sections but I don't think you need to do that yet
If you need to know how to do that, look into any of the merged PRs that have register settings in them. pylint doesn't like the extra whitespace needed to have them lined up readable.
So those are all disabled.
well...let me try it....
running pylint locally is what travis is doing, so if you pass locally, you should pass travis.
can you just use the label in paren of error message for the disable?
W:136,12: Unused variable 'i' (unused-variable)
so then...
# pylint: disable=unused-variable
I think so
I did it based on error number and Dan corrected me. So I think you just get the name from the error in pylint yes
i ended up just using pylint: disable=no-self-use for that one instead of a decorator
Ah nice. I really wanted to know why it was failing, so I looked into how to fix it, that's why I changed mine. Didn't end up needing it anyway. Changed how the method worked in the end.
yah, i might look into it a little more. one of these detail things. i actually tried refactoring things so it actually did get called, but it still complained. so dunno. went back to original and added the flag.
yeah
I am picking up SimpleIO.
@tidal kiln @idle owl i ran into "unused-variable" in a loop like yours. The code fix is replace "i" with "_".
Interesting. Thanks!
for i in range(0xff): # pylint: disable=unused-variable
rom, diff = self._search_rom(rom, diff)
if rom:
devices += [OneWireAddress(rom)]
if diff == 0:
break
for _ in range(0xff):
rom, diff = self._search_rom(rom, diff)
if rom:
devices += [OneWireAddress(rom)]
if diff == 0:
break
Odd.
it a python thing, not sure it is better
thanks. interesting.
it's also possible that the entire looping could be done more pythonic
it's inherited code with a c legacy
The name that is just a single underscore (_) retains the result of the last expression when you are working interactively.
Lutz, Mark. Learning Python (p. 355). O'Reilly Media. Kindle Edition.
pyLint is just complaining that i isn't used.
neat. doesn't look like that's in CP though:
python3:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.time()
1513203583.4167595
>>> _
1513203583.4167595
CP:
Adafruit CircuitPython 2.1.0 on 2017-10-17; Adafruit Trinket M0 with samd21e18
>>> import time
>>> time.monotonic()
84728.1
>>> _
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_' is not defined
>>>
It appears the underscore works iteratively as well from the code use.
Ahhh, good catch. It should be.
question about SimpleIO. There is a function called bitWrite() which is pylint says is invalid. do you know if there is any adafruit documentation that references bitWrite in SimpleIO?
We were just going through simpleio for something else. No idea on that though.
oh no no
ok
I meant literally looking through it for a way to use something in it.
this is what the comment says
Based on the Arduino bitWrite function, changes a specific bit of a value to 0 or 1.
The return value is the original value with the changed bit.
This function is written for use with 8-bit shift registers
Hmm
SimpleIO was supposed to make it "easy" to switch from Arduino to CircuitPython
i want to renam it to bit_write()
But need to know what that will break
i can leave it.
@fading solstice I'd be tempted to disable the variable namign check for simpleio because it matches arduino
ok, that is what i need to know thanks
@tidal kiln @lofty topaz thats a great catch. it'd be good to file an issue
@slender iron is it an issue? i thought it was just something not in micro / circuitpython
ideally we'd work like CPython. it won't be urgent
@lofty topaz want to file it?
it's implemented in MicroPython, so I bet we just have to turn it on
i just tried it on a pyboard
enable MICROPY_CAN_OVERRIDE_BUILTINS: that does other stuff too; not sure why it's coupled to that
Cannot find a rendered schematic for Circuit Playground Express 3333 on the website.
I already have my own in Eagle (which I suddenly remembered I'd created for my own use).
BIG NUDGE
@timber mango you could post something in the forums to remind us. There's a draft page in the Learn Guide but it's not populated yet.
or never mind: I'll pass it on
Appreciate it. It's been quite a few weeks now. Last time I asked, I believe I was directed to Eagle CAD (which was a good experience).
@idle owl just jumping into an old thread - even tho there are multiple tap axes, the CPX is too small/light to reliably tell which axis it is.
@timber mango I was able to get it to pretty reliably with some really specific code. Usually the mistakes it made were thinking it was the opposite end of the same axis, like it was bouncing back in my hand. But I've got it down to tweaking it to be reliable with any clicks. Left out axis detection for now for the API.
@fading solstice by the way, it's better to use .append() than to create a 1-element list and add it to an existing list
why didn't pylint find that one?
@stuck elbow talking about that onewire code?
I'm doing the review for that now too
it just matches patterns
I think you can add a check for this particular pattern, if you want
i like your suggestion, but cater is the one that needs to know
i did that. well i reused that. good point though. easy enough to change.
I know that operators often look better than methods
sometimes hard to think python and not c
but there is a funny effect of learning python -- your C becomes more readable too!
@stuck elbow did you comment on the PR about append?
I didn't see the PR, only the code pasted in here
I guess I should start reviewing the pull requests regularly
that'd be awesome!
should i have added reviewers or something to the PR?
@tidal kiln I got a notification about your PR, so it's at least sending those
@tidal kiln sorry, got a bit carried away with review
@stuck elbow your comments seemed good to me
yeah, but most of them are style, so should go into the second pass
@idle owl you should rarely use @classmethod. @staticmethod is more likely because it doesn't need a reference to the class either then
and often it's fine to just define a function
@slender iron That particular one didn't work as a staticmethod
I tried that first because I knew about it
@staticmethod is really only useful when you need to override it in some child classes
what would you do for crc8 @stuck elbow ?
@stuck elbow np. good comments. esp. about kwargs, first time i've coded for them.
@tidal kiln Just got back from dinner and saw the posts about the uderscore and filing it. You should do it if you haven't already. Sorry for the delay.
@slender iron a normal function, maybe name it with _ in front so it doesn't show up in tab completion
even with self ignored?
ah that'd work too
@stuck elbow @slender iron thanks for review. i have homework now.
๐ great work!
@tulip sleet looks like you were looking into that _ thing...do you think it's still worth an issue?
@tidal kiln it's worth putting an issue in just as a reminder. you can make it real brief and just mention that MICROPY_ flag as the way to turn it on. Thanks!
Enabled in MicroPython via MICROPY_CAN_OVERRIDE_BUILTINS flag.
But in CP:
Adafruit CircuitPython 2.1.0 on 2017-10-17; Adafruit Trinket M0 with samd21e18
>>> import time
>>> time.monotonic()
84728.1
>>> _
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_' is not defined
>>>
hi y'all - i'm having a problem with my feather - i can access it in bootloader mode, but when it goes back to circuitpy, i lose access to the keyboard/mouse on my laptop it's plugged into. what am i doing wrong?
I don't think you're doing anything wrong. There's a few things to try. You can try a different USB port or reboot your computer. The other possibility is that the drive on the Feather is corrupted. If you follow the steps found on the Troubleshooting page in the board guide, you can erase the board and start fresh. Let me grab the link.
ah, thx @idle owl
Make sure you backup your code first, the erase will remove it.
there's nothing on it yet - just got it from adafruit last week
@covert birch it's because CIRCUITPY is emulating a keyboard and mouse (though you're not using that feature).You probably have the internal keyboard and touchpad suprressed when an external one is plugged in. Try turning off that suppression.
That's a better option to try first
But here's the link to the Troubleshooting page if that doesn't help. https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/troubleshooting#circuitpy-drive-issues
hmm, ok. i only have a wireless mouse that connects via usb module
Hmm.
what OS?
mac 10.11.6
And you lose the built in keyboard?
yes, both
@pastel panther you are on el capitan as well right?
btw, you might want to know this is my first foray into circuitpython
i was kinda following along with tony d's video
@covert birch did you enable any assistive features?
no
I'm wondering if there's a setting somewhere that disables the internal kb when you attach an external one, and it's seeing the Feather as an external keyboard input.
Like disabling the touchpad.
I know of such a thing for trackpads: it's a setting on the trackpad driver options (have seen this on Windows). I googled this but I don't see an obvious setting.
but why is it seeing it as such if the case
It can emulate one, so it might be reading extra features of it once the CIRCUITPY drive mounts. I'm guessing here though.
Check both the keyboard/mouse settings, and try to dig into the assistive settings, because some of them are on by default or get turned on (somehow, I don't know, I've run into that) and mess with things you don't notice until something like this happens.
that i can try now
I've had to dig deep before to find the offending setting.
I haven't had an issue on newer mac osx
Neither have I but I'm guessing there's a rogue setting somewhere.
@covert birch did you install any drivers for your external keyboard and mouse?
Some stuff here, but migt not help: http://www.mackungfu.org/cat-proofing-a-macbook-keyboard
it's just this logitech trackball/mouse and yes, it has it's own config software that appears in the settings
i'm looking at it now
let me disconnect mouse and try it
one other person had trouble with the drive because they had a third party driver
yeah a weird one they didn't even know was installed.
ok, so there was a setting in assistive i've unclicked, and plugged in the feather, but now the feather isn't showing up at on desktop at all
it could still be in a Finder window. Usually doesn't show up on desktop
look in left sidebar in a Finder window
Does it show up as the bootloader? Or neither
did you switch to a different cable. make sure it's plugged in all the way at both ends
what did you change in assistive settings?
There are cables that only send power and not data, but you had a FEATHERBOOT drive before, right? So that probably isn't the issue with the cable.
Pulsing green usually means it's in CircuitPython mode and is happy.
do we have IR receiver support on CPy working?
ok, think i got it now. thanks y'all. gonna watch aae, but i'll be back with more questions i'm sure later
@split ocean Sort of? What are you looking for
@tulip sleet it was a checkbox that said ignore built-in trackpad when mouse or wireless trackpad is present. must've been set by logitech's software
@coral burrow I'd love to see you make a circuitpython video too!
@slender iron while vagrant is doing its thing, I was thinking about tossing the link to the MP-samd21 Build Firmware guide into RTD/GitHub. I understand that having a bunch of people building their own firmware might not be desired, as that may raise "I borked my board" questions. But, when it comes to contributing to the core stuff, it would be nice to have that EXCELLENT guide to get up and running. Thoughts?
Alrighty. now to pick the best spot... ๐
@slender iron His wish is your command. Now that's the way to manage a project.
lol. empowerment is a powerful tool.
๐
Great Wednesday Scott. From 3D Hangouts webcast to S&T and AAE, this is my favorite day of the week.
yup totally!
@slender iron Moved all of the non-express board running out of space stuff into the Troubleshooting page. It's in two places for now but I'm going to let Limor do the deleting when she's ready. Waiting to hear from her on a couple of questions, but otherwise I think I covered everything else she wanted covered.
this rst stuff sure puts up a fight! haha.
while I'm in the docs, anything anyone wants edited before I PR?
@slender iron Are interrupt handlers (ISRs, callback functions) included in CircuitPython?
I decided to knock out issue #243 (Improve explanation of safety of microcontroller.delay_us()) before I PR.
Does time.sleep() act the same way? want to give an alternative for the docs. only other thought is the arduino way, using millis()...
I think you're looking for time.monotonic()
@idle owl Are you talking about this sort of ISR implementation?
from pyb import Pin, ExtInt
callback = lambda e: print("intr")
ext = ExtInt(Pin('Y1'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback)
ok. so it would be...
stopTime = time.monotonic()
while (True):
currTime = time.monotonic()
if currTime - stopTime >= 1000: #stop @ 1 second
break
end
end
``` (its been a while since I Python'd; my syntax may be off)
no need for end
remove () around True
otherwise....
although, I wouldn't put all that in the doc. i would just reference the use of monotonic.
in arduino, you...hehe. ok. ๐
gotta turn my glasses on. ๐
proof test...
old:
Dedicated delay method used for very short delays. **Do not** do long delays
because it will stall any concurrent code.
new:
Dedicated delay method used for very short delays. **Do not** do long delays
because this stops all other code from completing. Think of this as an empty
`while` loop that runs for the specified `(delay)` time. If you have other
bits of code that require specific timing or processing while you are waiting,
explore a different avenue, such as using `time.monotonic()` to evaluate time
in a loop.
hmm. actually, it stops more than just code from running. to the datasheet, boywonder! :batman emoji:
shared-bindings/microcontroller/init.c: updated documentation for delay(), per issue #243.
docs/design_guide: added links to learning guides for building firmware (SAMD21 & ESP8266).
@raven canopy looking at your PR now
Audio recording is one example that will not run during delay_us. You can also point to time.sleep as an alternative for longer delays because it will actually use something like time.monotonic to do some things in the background while waiting.
This is a great place for these!
Alright. I wasn't sure if time.sleep caused the same behavior or not.
@raven canopy you around? did you get sphinx warnings about the delay doc?
@slender iron caught me just before shutting the rig down. no, didn't get any (but didn't necessarily check it either ๐ )
k, I think some of the stuff in single ` will cause warnings as it tries to find a place to link to
oh yeah. it's double ticks. i'll hook 'em up real quick.
๐
hmm. single ticks are used throughout that one. want me to update all of them?
let me look
single ticks are ideal when it can find the reference
so time.sleep should be single but while and delay should be double
I think the rest are probably ok
ok. so the time.sleep would be good with single, but the while and standalone delay will cause an issue. understanding....
yup, I think so
sphinx should warn about ones it can't find (it matches from the method and module names). its not smart about function arguments though
would it warn me on commit or PR? or would I need to go somewhere to explicitly check? (only travis checks were running on the PR)
running sphinx locally or read the docs after it was submitted
alrighty. i'm out. told myself I'd stop staying up this late... there's always next year. ๐ด
thanks @raven canopy !
Reading through https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino/circuitpython. How can I find out what bootloader/CircuitPython version I currently have loaded on the Trinket M0?
If you open the repl it should tell you the version number
@opaque patrol Thanks!
@cunning notch No problem, if you need anything else, just ask ๐
Just now getting around to CircuitPython/MicroPython stuff. I've been on RPI for a long time. ๐
Yeah, its pretty neat...I few years ago when someone suggested running python on a micro-controller, people laughed and now here we are
It makes sense.
I have to walk the line between Java/Android and Python. I think I smile more when coding in Python. lol
I do the same with javascript, c++ and python...
And I kick myself when I use a colon in javascript or c++
Most of my hobbies end up at work. I have over a dozen RPIs deployed running Python at work. I've been working on PLCs with HMIs for a while and now I working with Android for HMIs. It's a battle at times to decide if I want PyQt5 or Android. Android is smoother but takes longer. PyQt is python and, well, I like it more. Decisions, decisions.
I bought a Trinket M0, Feather M0 Express, and a Feather HUZZAH. Working on another automation controller. ๐
Well, a controller that doesn't require a $500 PLC. ๐
Fixed in 2.x by #479. Will ber merged into 3.0.
It's turned on in the Express boards builds, but not for Gemma M0, Trinket M0, and Feather M0 basic builds. It uses 24 bytes. We should turn it on for all builds in 3.0 definitely.
I don't have a reliable fix for this yet. I tried adding a delay before reformatting the filesystem (so an immediate powerdown during the delay would avoid reformatting), and also delaying and re-checking when the filesystem seems bad. I can still bobble the JST connector and erase the filesystem.
@cunning notch to check the bootloader version - enter the bootloader and you should see the file system TRINKETBOOT. If you open the file INFO_UF2.TXT it will tell you the current bootloader information. https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino/circuitpython-pwm?view=all#uf2-bootloader-details
Fixes #449.
Before boot.py is run, write version info to boot_out.txt.
Consolidates long version string into mpversion.h, since it's printed a couple of different places.
I was worried about flash wear, but it turns out boot_out.txt is already rewriten every time, even if it's empty. We could fix that sometime in the future, but this change doesn't make it worse.
dolt! just realized i've been running a 2.x pylinter locally. things look better running it with a 3.x version.
@solar whale Thanks!
@slender iron @stuck elbow updates to ds18x20 and onewire pushed based on review comments
36ec29d Documentation Updates (mcu.delay() and Design G... - sommersoft
This is in progress using pylint on our libraries. Its being organized in #475
No reply from the proposer so closing this PR. Please reopen if someone wants to pick it up.
@willingc or someone else please reopen this when its closer to needing a review.
@slender iron one sec though, i think i'm going to do one last tweak based on @stuck elbow 's comment about bus._readbit and bus._writebit
@tidal kiln ok. I think I'll go grocery shop now anyway
get it done so I can come back and focus
np, it's minor, shouldn't take long
Thanks @tannewt. Will do. Hope all is well with you too.
I am starting on HID
@slender iron Did you get my question from last night
on discord?
Yah
I think I missed it
Do you know if interrupt handlers (ISRs, callback functions) are implemented in CircuitPython? They exist in MicroPython but I don't know if they're ported, and I don't know how to check.
They may be interhited from MicroPython but its untested and therefore unsupported
Ok
@slender iron No reason to believe that any of the hooks are conditionally-compiled out? I've got a rotary encoder object that's currently using an update() [non-blocking API] that misses transitions occassionally and I'd prefer to use intrs. I thought that first I'd try to turn off interrupts between the two GPIO reads just to see if that changes anything.
But if you think that it's unlikely that I'm getting interrupted, then I guess I would expect no difference. Mechanical encoder being twisted at a reasonable rate.
They could be compiled out. I haven't looked into it.
OK, I'll see if I can figure out what's going on.
I'd say its likely that Python is being interrupted. Its not meant to be strict time
there are a number of interrupts that happen plus "background tasks" that happen between loops of the vm
I'm guessing you must use interrputs somewhere for wall-clock time maintenance or something. Maybe even systick?
But are those loops synchronous or async?
As in polled to look like an interrupt with a fake-async callout?
One of the libraries does this IIRC in main() outside of loop() to get around synchronization issues in the mainline code.
in Arduino.
It basically does the polling for you btw calls to loop() and calls your callback when it finds that an event has happened. Not bad for what it does, although of course users have to know that they can't while(1) in loop().
Is the Feather HUZZAHH ESP8266 compatible with CircuitPython?
Yep!
@cunning notch https://learn.adafruit.com/micropython-basics-how-to-load-micropython-on-a-board/esp8266
@idle owl @tidal kiln Thanks. That's the tutorial I couldn't find. ๐
Perhaps a link is needed on the HUZZAH page? https://learn.adafruit.com/adafruit-feather-huzzah-esp8266
@jovial steppe yup, systick is one interrupt, usb is another. gamepad is an example C module thats used to track state using interrupts more reliably
@jovial steppe @slender iron I did check the code to answer @idle owl's query. Python-visible interrupts are not available in CPy. In other impls the pyb class provides some callback routines, and in other impls machine.Pin.irq() provides an interrupt routine. We don't have those. These features were port-specific and so it's not even that it's turned off -- it's just not part of our port.
@slender iron Ping me when you're around. I need a chat about the tap API. Thanks.
@idle owl just got back
in prep for 2.2.0 release.
@slender iron @tulip sleet I take a took at gamepad as a potential model. A maintained-polled model works "ok" for a manually-operated mechanical encoder, but it needs one hack in it to make it a more tolerant to missed transitions, versus always giving up outright. For my target audience, writing C plugins isn't much of an option, so I'll have to look into providing custom C-coded pieces for things that I know that I need. So far, rotary encoder support is the only one that I know of -- so, not probably not so bad. Avoiding custom builds is a high-want, but it looks like something has to give here.
ty for getting back to me.
@jovial steppe not sure if it's useful for your use case, but there are dedicated encoder interface hardware options. basically outsource the counting to an external device and interact via something like spi.
@slender iron question when you're done chatting api with kattni
@tidal kiln That's worth looking into for the general case, but in my immediate one I already have a shield that has an encoder on A3 & A4, so I'm looking for a soft solution. Can revisit that when the MetroM4 comes out, or switch another platform down the road, like maybe to a PSoC6 with a real crossbar fabric.
Yeah, saw that already. But unless it happens to be pinned-out to my particular pins, the solution won't be ideal, even if the peripheral dupes them out to multiple places. If you have a good, handy reference to using SPI, I'll take it but don't spend any time on it. I've seen people use things like UARTs/SPI in the past to weird things like pre-smoothed DACs.
ty
Ideally the Atmel side will start doing things like PPS as they have on the Microchip PIC24 side of the house.
checkout the LS7366R:
http://www.lsicsi.com/#/products/Incremental-Encoder-Interface
datasheet: http://www.lsicsi.com/datasheets/LS7366R.pdf
and this is basically a ready to go breakout of that chip:
https://www.robotshop.com/en/pulse-count-module.html
I need some help connecting to my CPE. When I plug it into my computer it turns on, but it doesn't show up. I used the driver installer from the tutorial and checked to make sure the cable had data. Any ideas?
Yeah, there's no shortage of encoders/decoders in MSI parts. Our board is already what it is. One might as well throw another $0.25 MCU at it if you're going to off-chip your encoder. Like a SeeSaw -- programmable, customizable.
Although it ain't goin' to 20MHz!
But I don't know anyone with nimble enough thumbs to spin a mechanical encoder at 1M RPM...๐
@vocal shale what computer and os?
Did you ever see it work? Do you see any action on the RGB LED?
But you've not yet been able to speak to it the first time?
That's right.
So basically a fresh-outta-the-mail board.
Yep, came in the Adabox.
I'm using a different CircuitPython board (I don't have a CPE yet) but with power and data I was able to see a drive show up immediately. I'm also Win10.
Win10 doesn't need any special driver, so that rules that out.
I do think that there's an image download tool to un-wedge a messed-up board -- an interface that doesn't use the USB mass-storage method.
Ah.
Wait a second I plugged it into another port and it showed up.
That's probably the access method for the other initialization tool (Bossa, I believe). For my board it's documented how to use that in case the USB mass-storage doesn't work, but out of the box that shouldn't be necessary.
Yeah, if you talk about electronics, sometimes they get scared and start to work.
Haha yeah
Just like us sometimes.
Windows is just like insanity. Sometimes you have to do the same thing over and over trying to get a different result.
is the behavior repeatable? won't work in the one port, but does in the other?
Might be a marginal cable, too. Either end could be wonky.
ouch hrm reading an analog input on m0 seems to take 10ms
do we have an explicit delay built in perhaps?
Or as @tidal kiln says, maybe the port is sloppy. I have at least one of those on my laptop.
trying to see how fast i can sample ADC.. not promising with 10ms per sample :/
hola
Has anyone messed with circuit playground? It has GPIO, but the only thing I can get working is capacitive touch. I can't really find any resources on using the gpio other than touch either
@final night have you looked through the learn system?
I thought I did haha. I guess I'll go back and check it out again
a better question may be, when did you look?
a lot of things are being added and updated right now, and on going...
this one's a bit buried, but goes over analog in: https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-analog-in
Just found that one haha
this one is general, but covers circuit playground, digital in / out: https://learn.adafruit.com/circuitpython-digital-inputs-and-outputs/digital-signals
Is circuit python syntactically different than python in basic stuff? Like could I write a Blinky program the same way?
HEY
can somone check my arduino code?
in projecthelp?
im wondering why the the real pressure is only printing 0
@final night circuitpython is python3, with a few exception due to the limited hardware. but in general, just pretend it's python3.
ah, cool cool. Does the same apply to micropython?
pretty much, circuitpython is a fork of micropython
@inner wagon this is for CircuitPython.
@timber lion AnalogIO reads from the ADC twice, because it doesn't know what state it's in, and if the ref voltage has changed, the first read is not reliable. Clock is being divided by 128. Looks like it's running at 375 kHz and it might take 16 clock cycles to read. But it gets enabled and disabled. don't know how long it takes to get set up.
@jovial steppe if you add a C helper for toary encoder it'd be awesome to have it added to core CircuitPython like gamepad is
This may be an Arduino implementation artifact. Since Arduino lets the user sloppily flip back and forth between using an analog pin and digital pin statelessly, they have to go through ADC setup every time in a worst-case fashion. If CP can/wants to reserve a pin for one or the other use during the lifetime of a created object, there are almost certainly setup optimizations that could be made to short-curcuit much of them. Maybe even let the ADC free-run during the life of an AnalogIn object.
You'd probably have to tie together all of the AnalogIn pins' configs though, since they're all mux'ed together.
@slender iron I'd be willing to look into that. I haven't done any ARM development yet, although I probably have all of the hardware to do it. Do you have a cookbook for dev-env setup, or is Atmel Studio all that's needed? I'm Win10, but I haven't used AS since version 4.
and only on AVR8.
I do have an Ulink-EDU around somewhere unused in a box.
@slender iron Here's my existing soft encoder impl which works "ok". Let's see if/how cut-N-paste works...
@jovial steppe Surround code in three backticks (top left of keyboard) to create a codeblockIf that's what you're wondering how to do.
If it's that big, it might work better elsewhere
It's hard to read and discuss huge codeblocks here.
Comments are great though!
`# This CircuitPython class implements a software, polled encoder object.
It's polled because at the current time there no support for interrupts or
hardware encoders on the M0.
Construct one by supplying the two board.Dnn pins.
The return value is a triple composed of the running count, a boolean
indication of a non-recoverable error, and a boolean indication of whether
a recoverable error occured.
This seems to work well enough to be useful with a 20count/rev mechanical
rotary encoder spun manually at a reasonable rate of speed without too
many errors (which can usually just be ignored depending on you needs).
class PolledEncoder:
ch1 = None
ch2 = None
state = 0b00
count = 0
lastChg = 0
`
` # Ex. PolledEncoder(board.D17, board.D18)
def init(self, ch1, ch2):
self.ch1 = DigitalInOut(ch1)
self.ch1.direction = Direction.INPUT
self.ch1.pull = Pull.UP
self.ch2 = DigitalInOut(ch2)
self.ch2.direction = Direction.INPUT
self.ch2.pull = Pull.UP
if self.ch1.value:
self.state = self.state | 0b10
else:
self.state = 0
if self.ch2.value:
self.state = self.state | 0b01
`
` def update(self):
err = False
fixedErr = False
c1 = self.ch1.value
c2 = self.ch2.value
if c1:
st = 0b10
else:
st = 0b00
if c2:
st = st | 0b01
if self.state == st:
return (self.count, False, False)
if self.state == 0b00:
if st == 0b01: chg = -1
elif st == 0b10: chg = 1
else: err = True
elif self.state == 0b01:
if st == 0b00: chg = 1
elif st == 0b11: chg = -1
else: err = True
elif self.state == 0b10:
if st == 0b00: chg = -1
elif st == 0b11: chg = 1
else: err = True
else: # state == 0b11:
if st == 0b01: chg = 1
elif st == 0b10: chg = -1
else: err = True
if err:
# This is a kludge to deal with some missed transitions -- assume
# that the missed transition was in the same direction as the last.
#print("ERR:", self.state, st)
if self.lastChg != 0:
chg = self.lastChg
self.lastChg = 0
err = False
fixedErr = True
else:
self.count = self.count + chg
self.lastChg = chg
self.state = st
return (self.count, err, fixedErr)
`
It's basically a re-entrant impl. You just keep calling update() as often as you can to see if anything's changed since the last call.
I haven't fully unit-tested it yet, but the happy case works well enough.
@slender iron just PR'd the lingering onewire items
My Python is three-years rusty but I'm refurbing. So probably not as pythonic as it could be. Would like to know how it could be better/more-concise.
Can you create files with circuit python on the circuit playground express? I'm looking at the documetnation and it looks like you can, but it's not working for me
Should be able to if it works like the non-CPE boards. There are some editor-specific gotchas though, but may only come into play once you're (re-)writing-out files for execution. You could always create them locally and drag on onto the board the first time, just for fun.
Some editors don't write out files completely to fake-flashstick devices in some circumstances (that's the gotcha).
Notepad++ seems to be one editor with said issues. I use Emacs which works, but Emacs isn't for everyone.
This is what I have so far. It works like ths, but when I uncomment the file lines it doesn't run
import digitalio
import board
import neopixel
import time
f = open ('output.txt', wt')
f.write('test output')
f.close()
get the status LED by the USB port
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
#led.value = 0
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness = .2)
pixels.fill((10, 0, 0))
pixels.show()
@slender iron FYI - that residual cookiecutter template stuff was my bad. i was trying to do a manual copy pasta update. obviously i didn't understand how it works. ๐ฆ
@flint oyster I'm no python expert, but it looks like you've got a mismatched single quote in the open() call.
When in doubt, add code one line at a time when it comes to syntax error tracking-down.
oh yeah, that would affect it
Nice to meet you too
@tulip sleet ah hrm I think we should look at ways to speed it up. does arduino do the double read i wonder? i did a test to compare to arduino and it's 0.4 milliseconds for an ADC read vs. 10ms for circuitpython.. ouch big diff. with arduino it typically pushes filtering down to the user's code, so if you get noisey values do smoothing there (many arduino ADC sketches do a buffer of 5 samples and average them for example). i think we want the same approach
Tried fixing it, still has issues
import digitalio
import board
import neopixel
import time
f = open ("output.txt", "wt")
f.write("test output")
f.close()
get the status LED by the USB port
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
#led.value = 0
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness = .2)
pixels.fill((10, 0, 0))
pixels.show()
@timber lion I'm writing an email -- should have some numbers and info for you soon.
@flint oyster I don't have a CircuitPlayground nor have I done file I/O, but I'd be concerned that there's a module that needs to be imported to allow you to write to the file system. Unless you've seen an existing working example that shows that's the way to deal with files on CircuitPython, that's what I'd suspect. What you're doing is fine regular Python though.
@flint oyster when you say "it has issues", do you mean writing to the file or with the neopixels? You have the brightness set to .2 and only setting the r value to 10. This may not be high enough to see. Try bumping it up to 155 or higher and see if that works (max value for r, g and b is 255)
The issues I referred to is your editor of choice not flushing your code text out to the board when you write/save it to have it run.
@flint oyster by default you can't write to a file from python because your computer can. Check out this learn guide for how to do it: https://learn.adafruit.com/cpu-temperature-logging-with-circuit-python/writing-to-the-filesystem?view=all
There you go. Didn't anticipate that you could write files to the flash filesystem just like regular Python.
@slender iron That looks like what I need thanks.
Everyone should have their own tannewt.
if you get one now, it won't be tan until summer
Gotta start somewhere. It takes three seasons to get edible asparagus, too.
Really, I never thought asparagus was edible
Lol. How do you think you can make pee smell that way otherwise?
Don't get me started on the veggie wars.
I've been practicing for decades on the emacs-vs-vi wars. I will crush you!
Emacs rules!
no bash ing allowed
Bash, as the successor to "sh" is clearly The Good Side. "csh" script writers also need to be shot alongside their "vi" users.
I love how "Tr ump" is in the censored language filter.
I'm finding them all firsthand.
Forgot to mention that I served as a general in the Spaces vs Tabs wars too. I have "the best" decorations.
You wouldn't believe it. Noone knew someone could earn so many medals.
I got a file written HUZZAH!
Excellent. We knew you were better than they were!
The dark forces of programming have been vanquished.
@tidal kiln I got digital input working. Thanks!
@final night yay! np. glad it worked.
vagrant is putting up a serious fight right now...
so I totally missed documentation issue #448 last night while I was docupdating. got it done, but now when creating the PR, it wants to push the commits from last night that were already merged. does that seem odd?
@tdicola has measured that AnalogIn.value takes about 10msecs per sample, which is very long. Currently it takes 16-bit samples with the 12-bit ADC using the builtin decimation and oversampling. This means it takes 256x the normal time: decimation and oversampling is 4^n.
In addition, there's a clock divisor which is set to 128 and could be set to 32 now, gaining another factor of 4. And finally, two readings are taken for each reading, in case the reference voltage has changed beforehan...
I changed to prescaler division 32. Using the test program below (a slightly sped up variant of @tdicola's), I get these measurements. The "none" measurement is not using the ADC at all, just returning a fake value immediately from the low-level routine.
| bits of resolution | sample time | samples per sec | num times ADC is read per call |
|---|---|---|---|
| none | 0.17ms | 5800 | 0 (measuring overhead only) |
| 12 | 0.29ms | 3450 | 2 |
| 12 | 0.28ms | 3500 | 1 |
| 13 | 0.33ms | 3030 | 2 |
| 14 | ... |
yah the intention w/16-bit value is that 16-bits is greater than the resolution of microcontroller's ADC resolution (which is 10-bit or 12-bit...maybe rarely 16-bits but as you can see that is terribly slow). and its an int so cleaner, clearer and easier to compare/do math with.
default, the ADC should read whatever is the native rez (12-bit for M0/M4) then pads 0's for the bottom 4 bits
for reading audio, even arduino cannot sample analogRead() very fast, we would always set up a...
oh good, getting analogIn to go faster ๐
Lower ADC prescaler divisor from 128 to 32. Lower resolution from 16 bit to 12 bit. Fixes #484.
@slender iron @idle owl is LIS3DH ready to be re-frozen? Latest PR is approved but not yet merged. Tnx. Maybe waiting for @timber lion review?
@raven canopy when you are back I can help with git
@tulip sleet if you are ok with it too I think its ok to merge
@slender iron it looks ok if you've tested
yup I tested the three examples I changed
good enuf
@idle owl has too I think
I'll make a new PR. Won't bother for a review, since it's just a submodule update. Are you OK with the AnalogIn fix?
with the test program in https://github.com/adafruit/circuitpython/issues/484 and with a simpler program: a loop with reading a potentiometer voltage divider
ok cool
@tulip sleet want me to do a 3.0.0 LIS3dh release?
sure, then it will be a labeled release for the frozen module in 2.2.
yeah, I don't think we should freeze non-released versions of libraries
Is audioio a builtin module?
I believe its only enabled on express builds by default
Okay, I was trying to use the trinket, I will switch to an express board
Just to make sure we don't lose it, this was one thing discussed in the email thread.
From Dan: "So, in the short run, I can speed it up by x4 immediately without losing accuracy. Do you have some feeling for what to do for 2.2? For 3.0 we can do whatever. In chat Scott mentioned returning a float voltage value. We can add ".voltage" later, say in 3.0. I can also add some optional args that set the precision and/or scale the output if it's integer."
My thoughts for ADC, similar to volta...
@tulip sleet @slender iron Thanks!
for CircuitPython 2.2.0 release.
Also to clarify, Dan mentioned "Tony proposes reducing to 12-bit to allow at least audio sampling." Actually I proposed speeding it up for all uses, not just audio. Right now for example we can't reliably catch a fast knock or signal when sampling a piezo. 10-20ms period or 50hz sample rate is just too slow unfortunately and frequently misses any quick impulse, like a sudden spike from a knock. If using timer & DMA is the desired way to go then should we open a new issue to add these for ...
@slender iron I was going to test amg88xx last night but it looks like it needs to be rebased. I evidently only understand how to read what it tells you is supposed to be changed if I'm the one who wrote it because it looked really confusing to me. Or I would have done it myself.
@slender iron do you mean the power-down SPI erase bug or an amg88x bug
There isn't one that I know of, I was saying the PR needs a rebase
i didn't know if there was an amg bug or not! I do have a tentative fix for the power-down bug but it's not perfect. I have a closed PR but I could put it in anyway. It's not more dangerous.
nah, lets sit on it
@slender iron after sleep, I think I have a plan. I need to pull from Adafruit/CPy to sync my fork...then do a PR for my new changes. Don't know why that didn't occur to me last night...
I feel like we're rushing too much into 2.2
we should just call it good after the lis3dh stuff
that's fine
we can always do 2.3
@raven canopy are these doc-only changes?
@tulip sleet yes. Issue 448.
@raven canopy yup, I think you are on the right track
Adding audiobus to support matrix. @tulip sleet
if you do this now I'll put it in 2.2. should be quick.
Yep. Luckily I can GitHub at work. Doing it now.
or are you doing it on master?
Yep
You want on 2.x?
if you want the experience, sure. I will merge all changes from 2.2 to master in a big PR, so you don't need to do both. So git fetch upstream [or adafruit]; git checkout 2.x; git merge adafruit/2.x; git checkout -b 2.x_448_audiobusio_support_matrix; [do your change]; git push
Can only run GitHub at work, unfortunately. I'll just drop it to master to keep the confusion down. @tulip sleet
@raven canopy np!
yep we will do both things!
-
reducing M0 and M4 to 12-bit (no oversampling!) and pad LSBs with 0's - that is the intended interface and it's in 2.2 now, you can pull and try it!
-
add a blocking DMA interface for ADC reading at high freq rates, in 4.x (i'll create an issue)
for getting float/voltages for ADC, we can add helpers in SimpleIO! :)
12-bit and prescaler divisor fixed by #485 for 2.2.0.
for some applications, we want to grab a chunk of samples from ADC at 'fast' (16KHz!) fixed periods. lets think of a way we can request an array of 16-bit values that will be popped off the ADC pin at samplerate
Perhaps this would be AudioIn? To correspond with AudioOut
This would be used for lots of things beyond audio though--sampling any signal from the ADC, like a piezo, light sensor, load cell, etc.
Yah - i think its the mirror. technically its not just for Audio, and i dont think we'd do WAV translation? but maybe we would?
it would still be padded to 16-bits but perhaps a .resolution setter? see similar https://www.arduino.cc/reference/en/language/functions/zero-due-mkr-family/analogreadresolution/
Low priority!
I'd definitely add a getter to read resolution, maybe even in 2.2? This would get people into a mode of using the resolution as read from the hardware in their code early. It would allow changing the resolution easily in the future (as people wouldn't bake in the 65535, etc. limits like we do today).
we'd still pad to 16-bits so there's no change in API! resolution changes the precision of that 16 bits only
Ah gotcha, one thing it's pretty uncommon to have a write-only property in python. Typically there's always a getter to allow you to see what state the property is in without keeping track of it yourself.
Would the getter for this resolution prop always return 16-bit though? I.e. I set to 12-bit, 8-bit, etc. but always read back 16-bit since it's internally scaling?
I've targeted 2.2 as mostly fixes; 3.0 or later makes more sense for API changes/enhancements
edited to change it to 'property' rather than setter
@slender iron ```python
def double_tap():
tapped = lis3dh.tapped
first_double_tap = tapped and not self._last_tap
self._last_tap = tapped
return first_double_tap
Actually so does the first version you sent me.
I did not
Still returning true. Here's what I have: ```python
last_tap = False
def double_tap(self):
tapped = lis3dh.tapped
first_double_tap = tapped and not self._last_tap
self._last_tap = tapped
return first_double_tap
while True:
if double_tap:
print('Double tap!')```
It's not in express class yet, this is trying to get it to work in code first.
If I make it self._last_tap above it, I get self not defined because it's not part of an init yet.
in your loop do double_tap() since its not a property yet
and self should fail then
TypeError: function takes 1 positional arguments but 0 were given
exactly ๐
last_tap = False
def double_tap():
global last_tap
tapped = lis3dh.tapped
first_double_tap = tapped and not last_tap
last_tap = tapped
return first_double_tap
while True:
if double_tap():
print('Double tap!')
Ok, why does that work?
the original if double_tap was checking if the double_tap variable was True and a function value is True
self is only added implicitly when you call a function on an object like cpx.double_tap()
Ok, what does the global last_tap do?
since you called it directly, it was "static" aka unrelated to a specific object
global last_tap tell python you want to use the one you defined outside the function rather than create a new one inside
without global I think it'll warn you are reading before you assign it
>>> def foo():
... return False
...
>>>
>>> if foo:
... print("hello")
...
hello
>>> if foo():
... print("hello")
...
>>>
I originally had it with parens but removed them when the self bit failed, thinking that would fix the rest of it.
Thanks!!
one of those python gotchas. it will continue to work, but with behavior you probably weren't expecting.
and for global example:
>>> foo = 23
>>> def global_test():
... new_foo = foo
... foo = 42
... return new_foo
...
>>> global_test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in global_test
UnboundLocalError: local variable 'foo' referenced before assignment
>>> def global_test():
... global foo
... new_foo = foo
... foo = 42
... return new_foo
...
>>> global_test()
23
>>> foo
42
>>>
Hmm
PyCharm is complaining. I'll see if it works. Nope, can't even mpy-cross it. Hmm. I'm supposed to put self._last_tap = False into _init_ ?
but also watch out for doing this:
>>> foo = 23
>>> def global_test():
... foo = 42
...
>>> global_test()
>>> foo
23
>>>
Hah! Fixed it. Essentially anyway ๐
The last_tap's don't want self._ before them.
So it looks like this in express class: python @property def double_tap(self): global last_tap tapped = self._lis3dh.tapped first_double_tap = tapped and not last_tap last_tap = tapped return first_double_tap
with this in _init_: python self._lis3dh.set_tap(2, 18, time_limit=4, time_latency=17, time_window=110) self._last_tap = False
no need for global in the class because you have self now
nope, just switch back last_tap to self._last_tap then
good work!
Thank you ๐
you too!
@slender iron Can you take care of the PR currently open for CPX?
Thank you!
thank you for fixing it up!
@slender iron So something like this Detect a double-tap on the device. Quickly tap the CPX twice to register a double-tap event. for RTD? I wasn't sure whether you wanted me to get into more explanation there or not, after everything we talked about.
@idle owl maybe "True once after a double tap."?
Added to that or instead of?
instead of
ah ok
Detect is a bit weird because its after the fact
Should I leave the second sentence in then? Explaining how to do it?
or use "Quickly tap the CPX twice to double-tap." sounds weird, but maybe it's needed? dunno
Actually I'll add that after the image, like we did with explaining how to "move the board" to change the values printed by acceleration.
I think it works there. Right before the code.
yeah, that sounds good!
@slender iron Ok one more PR for you. Once that's done I'll update Limor on the situation.
Wait, I misread that. I did the attribute error for CP being too old. But that's the issue, right because lis3dh is frozen? So if it's not working, it's your CP that's too old correct?
@slender iron let me know if that's not what you were looking for. changes are pushed.
right
ok keen
since we explicitly use the built in version
OK yep, I second guessed myself when I reread the change request is what it was.
Yay rc1!
<@&356864093652516868> (and anyone else) 2.2.0-rc1 release candidate published https://github.com/adafruit/circuitpython/releases/tag/2.2.0-rc1. Feel free to test!
github seems to have moved the downloads to the top and called them "assets". not sure i like that
I saw that, for some reason I thought that was our change.
i'll be out for a few hours for an early dinner - see ya
Hi all, I've got a crash happening when using IR remote on CPX that I could use a hand in figuring out.
here's the crash message in REPL:
File "main.py", line 56, in <module>
File "/lib/adafruit_irremote.py", line 163, in read_pulses
MemoryError: memory allocation failed, allocating 512 bytes
@split ocean can you post the code you are running in a gist?
i'll post a Gist
@split ocean Is the file adafruit_irremote.py in your lib folder actually .py or is it a .mpy file?
Did you change anything in it or did you use it from the repo I sent you
I got it here: https://github.com/adafruit/Adafruit_CircuitPython_IRRemote
just grabbed the .py there
Let me make you a .mpy to try before we dig into the code. It's quick and worth a try
super! thnx
@split ocean
Remove the .py and put that in there instead
This may not be the issue, but it's a quick step
OK, swapped it and still managed to get same crash.
File "main.py", line 56, in <module>
File "adafruit_irremote.py", line 163, in read_pulses
MemoryError: memory allocation failed, allocating 1024 bytes
Press any key to enter the REPL. Use CTRL-D to reload.
No I think it still sees it as a .py...
k
its not crashing on import, its crashign when its trying to read the pulses
correct
oh
it works for a while
then after a few successful color changes from the remote, it crashes
ok
@split ocean Great job with this though! I'm really impressed ๐
thanks!
those arrow buttons were meant to change the brightness, but I can do that w the color value instead, eh?
yup
BTW, the crashing seems to be when I use the arrow buttons or soon after
so great deduction.
Yeah that's how we were controlling brightness before we figured out cpx.pixels.brightness worked. Just set it really low in the RGB call.
thanks guys, I think you've cracked the case! I can't get it to crash it seems if I lay off the brightness calls.
oh crud, I spoke too soon
just crashed it w color changes
yeah, interesting
those were a lot of rapid calls on the things, I hit color buttons over and over pretty quickly
sounds like a memory leak or memory fragmentation
ok give me a minute to finish something up and then I'll grab the remote and I can actually test and see how it's working.
is it plugged into usb?
OK thanks much. I just had a crash after only three button presses, so ignore my previous theory
yes, plugged into USB
w REPL open
it should work better when its not
(there is a 4k buffer that gets allocated to help with writing files when on usb)
don't forget to do a nice eject!
@split ocean lurking, but are you turning off pixels after each press (like 0,0,0)?
just a guess - maybe try turning off the pixels when you dont detect a press on the button (i.e: button up vs button down)
no @dim lava just doing a fill of the new color. should I try blanking them first?
freaky, the thing is much more crash prone on battery power it seems.
Hmm. Getting a CPX ready for testing
wait, scratch that. fresh batteries seems to fix
(just finished my last final, so ill be in here more often over break)
yay!
nice!
discrete time linear systems and signals was a pain, but I learned a lotta theory that I didnt know so thats good
getting back to that though, ive done IR remote + neopixel with blanking when they're not pressed (@jp check your PMs, sent you some code)
OK, still able to crash it on battery power w either the brighness change buttons or the color change buttons
I fixed a crash when the decode fails
in the except clauses add continue
so python try: code = decoder.decode_bits(pulses,debug=False) print("Decoded:", code) except adafruit_irremote.IRNECRepeatException: # unusual short code! print("NEC repeat!") continue except adafruit_irremote.IRDecodeException as e: # failed to decode print("Failed to decode: ", e.args) continue
with try indented
k
Having trouble crashing it after that change!
Even changing brightness isn't crashing it
@split ocean a style thing would be that you don't need () in the if. so if(command == 103): # 8 would be if command == 103: # 8
thanks
hmm, I'm still crashing, and also having a lot of cases where it recognizes and decodes the ir blast but doesn't light the neopixels
I was able to do it a ton, really quickly and it took a long time to crash it
@idle owl sometimes it takes many presses, other times it's after one or two hits
it seemed pretty similar on battery, so I'm back on USB
I finally put it in 2 hands and tried to change it as fast as possible and this time it crashed with "list index out of range" but it took a ton of effort. I commented out the 3 ifs at the bottom and changed cpx.pixels.brightness to 0.5, and added Scott's change from above.
quick test of 2.2-rc1 on metro_m0_express and CPX - no problems - On metro_m0 tested i2c (bme280) PSI (Sdcard read on Adalogger wing) , nepopixels , UART ( GPS) - On CPX - just dis spinner demo, and accel demo.
@tulip sleet I just upgraded the FeatherM0 Express I'm using for the library I'm working on. No problems. Tried mpy-cross. No problems.
ooh I got the memory issue
Now I keep getting list index out of range. I added a time.sleep to the IR reading. python try: code = decoder.decode_bits(pulses, debug=False) time.sleep(1)
cpx is huge
Was wondering if it wouldn't run out as fast if it wasn't reading as quickly
means it's not as responsive, because there's 1 second between readings.
memory after board: 15824
memory after ir: 11888
memory after cpx: 832
memory after import: 528
memory before: 96```
wait don't trust that
wasn't collecting gc first
Ah
memory after board: 16400
memory after ir: 13504
memory after cpx: 5424
memory after import: 5120
memory before: 4688```
commence trusting
It is big though, I know this. The endgame idea was to freeze it too. But we wanted to get everything else added to it. All that's left is the soundmeter if we want it, and IR which is low priority. Seems like we could freeze it for 2.2 if we wanted.
Is this the correct place to ask for helpwith trinket M0 + neopixel + circuitpython issues?
yup!
Is there some way to clear things every few loops or something? I mean it works for a few tries, then fails, so something must be building up? Or is it clearing every loop and every so often there's a loop that's too big in itself.
can set a counter, not a very good solution though but it'll confirm if that's the issue
ok, I have a trinket M0 plus a neopixel 24 ring, I've updated the trinket to 2.1 and dropped the newer neopixel library into lib. Tried following https://learn.adafruit.com/kaleidoscope-eyes-neopixel-led-goggles-trinket-gemma but it wasn't lighting. I've managed to get it to light using a rainbowcyle demo, (I'll paste code as soon as i figure out how), but the full demo here doesn't work https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-neopixel It doesn't run on usb, and on battery i get blink codes. Also I get no output in serial console no matter what i print. Any ideas what I'm doing wrong?
@idle owl it should clear as it needs it
ah ok
I think we may need a limit to how many pulses read_pulses can return
I'm not getting memory allocation failures lately, I'm getting that list index out of range in reference to command = code[2]
@charred spindle could you try dropping your code in here: https://gist.github.com/
I changed it to use neopixel instead to see if it was cpx being too big that was the issue. But the list thing was happening with cpx as well.
Oh wait I think the list index issue is related to code not specifically command
Do it up
Tinket m0 + neopixel 24 ring. blinks R, G, B, unmoving rainbox, repeat. Only on batter, not on usb. using pin 0 data, pin bat for pwr, pin gnd for gnd. This works.
except that it doesn't work with usb plugged in, even while battery is plugged in.
oh, the rainbow is slowly moving!
I tried with this code and get nothing https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-neopixel
@split ocean Do you want to try some changes to the code?
(i adjusted pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.2) to match the other code)
what do i need to do to test this while connected to usb, the constant unplugging is not what i expected, and serial console over linux screen isn't printing anything but >>>
There are a lot of other changes that would have to be made to that to work with your bigger ring
@idle owl yes
@charred spindle If you're seeing >>> press ctrl+D
@split ocean Try this. I changed it to not use cpx, for testing purposes, added an exception for the list error I was running into. I haven't crashed it since I fixed this, but that doesn't mean it won't. https://gist.github.com/kattni/680c103f0de3e6a7f1646646b89616f0
beyond the board, and pin? ```pixpin = board.D0
numpix = 24
pixels = neopixel.NeoPixel(pixpin, numpix, brightness=0.3, auto_write=False)```
Yeah. I think some of the math assumes you're using the Circuit Playground Express. Maybe not, but at a glance it looks like it might.
The lights don't light on usb at all when using this https://gist.github.com/anonymous/c9b8a9a6cae8fdd131e5da1867a3df52
Tinket m0 + neopixel 24 ring. blinks R, G, B, unmoving rainbox, repeat. Only on batter, not on usb. using pin 0 data, pin bat for pwr, pin gnd for gnd. This works.
Could be wrong though. But if you're seeing >>> in the serial console, you're in the REPL and your code won't run.
@idle owl excellent -- that code has no desire to crash it anymore
Is your ring RGB or RGBW?
so how do i see print statements? as soon i as get these neopixels working I plan to wire in a temp sensor, where would i see temp outputs while testing
I don't see why that code wouldn't work.
should i just stay away from cpx w ir for now?
@split ocean Is it working for you?
RGB
@charred spindle Ok then that's not the issue. You see print statements in the serial console. But only when there is code running, and you're not in the REPL. Which is the >>> prompt.
I corrupted my Trinket MO's main.py. I attempted to create a copy, too. However, it seemed to be taking too long to get it to run and I pressed to reset it - twice! I now see both files as having zero-bytes. But, I cannot delete them. And, I cannot over-write them. But, after creating a new file, named it code.py file, that worked okay. I can edit it, copy it, save it, and delete it Any idea how to clear out the corrupt main.py and main_copy.pyzero-byte files?
ok. as soon as i get my code running while attached to usb i'll give serial console print statements a shot. Any ideas why this doens't run on usb?
@median shadow Sounds like your whole board isn't corrupted, but you might try following the instructions for when it is to get rid of those files. They're on the Troubleshooting page of the Trinket M0 guide. https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino/troubleshooting#for-the-gemma-m0-trinket-m0-feather-m0-basic-proto-and-feather-adalogger
@median shadow Backup anything you can though, that will erase the board entirely.
You will need to reload CircuitPython when that's done.
The other option is to try to delete them via command line if you have access to a terminal program - this is easier on MacOS and Linux than Windows.
Have you loaded CircuitPython before?
@charred spindle Not sure, no. There's obviously something unhappy. Do you have the appropriate libraries loaded on the board?
@idle owl yes!
Yes - I have loaded it before using the uf2 method. As for libraries, they are okay. I even copied libs from Github for one device and these seem okay, too. Just trying to erase the corrupt files seems to be the issue. I'll follow te instructions above. Thanks!
@split ocean Ok nice! I'm going to discuss freezing the library into the CPX build, but until then, evidently it's a little too much for the IR code to handle. So go with what I sent you, try adding brightness back in and so on step by step.
@median shadow You'll need to use the uf2 you previously loaded when you're done erasing it. Same process you did when you loaded it before!
@idle owl okay
@split ocean Also if you want the red LED back you'll need digitalio so if that's a funcitonality you want, maybe try that first to make sure it doesn't cause memory issues adding it.
ok, got it
@split ocean Also I would remove it printing "code error" just take that print statement out completely so it's python try: command = code[2] except: continue
That was for me to make sure it was working.
thanks again @slender iron and @idle owl
For sure! Let me know if you need anything else!
OK, I need to run in a second, but I have some questions for you later about running animations while still listening for IR blasts...
Excellent, I'll be around! Ping me when you're back.
@charred spindle My suggestion would be to step back your code, start with something simple that just prints, see if you can get the serial console working. Then move from there. Start from a place of known good code and then move into more complicated stuff. The serial console displays (sometimes vague, but still) errors so once you know it's working, it should help you debug why the LEDs aren't working right.
jumpered USB to BAT pins with battery disconnected and I'm getting serial console and lights
@idle owl My Trinket is back up. However, a couple of Oops! Should I have tried to save the .Trashes files first? How important are these?
Shouldn't be a problem at all, the only thing you would have wanted to save is your code.
Everything else is either an artifact of the OS, or can be reloaded like libs and so on
@idle owl Thanks much!
For sure! Great job!
What's the best way to ensure code is loaded to trinket m0? Code changes are not taking effect after saving file.
until I unplug/plug usb
What OS are you on and what editor are you using?
Wait, you have serial console? You can use ctrl+D to reload, or ctrl+C to interrupt and then reload.
But it should reboot on its own.
linux, and whatever text editor comes with xfce,
Ok that's good, you shouldn't run into an issue with it reloading before it's done writing, then. But I'm not sure why it's not reloading on its own once it's done saving.
I can switch to vim if there is good bindings, it just keeps popping up and so I'm using it there
You should be good, it was more whether or not you were on Windows.
Editor shouldn't matter.
didn't dan do some linux editor delayed write testing the other day?
I think it can be
not 100% sure, but thought some of the gui ones had issues
from a linux command line you can run sync to sync the file systems
@charred spindle ^^
Dan did point out a few days ago that it's not necessarily a platform-specific thing only. Some editors do go out of their way to flush their data and parent directory entries so that The Right Thing(tm) happens. Emacs is apparently one such editor (even on WIndoze) and NotePad++ (from personal experience) is not.
vim is good; it does a sync on each file write.
@tulip sleet Should we consider freezing express?
@idle owl I think so, when there's a version that you consider stable. Then it works out of the box and no mem problems. But it's been evolving a lot. So when you think it's ready for that. It should be pretty well tested.
Originally I though it might have been frozen a long time ago, but it wasn't ready at the time, and it didn't matter so much.