Closed deadprogram closed 10 years ago
@kehribar I don't know what this means.. is this something littlewire can do? I do have a wii nunchuck so perhaps I could hook one up as a testcase and finally implement i2c support. @deadprogram I tried to translate i2c code from the official C littlewire library, but I've never actually used it. Same for SPI and OneWire. I think OneWire even just raises an error saying it isn't implemented yet. I always figured I'd find a use for these things eventually and implement them, but so far that hasn't happened. I could really use some help, or even just someone could write a ruby script showing how they wish the littlewire ruby library worked, and tell me how to wire up a thingie (I have a nunchuck which is i2c supposedly, and I have a OneWire temperature sensor somewhere that someone gave me) and perhaps I could get it to work.
Even better if someone posted me a digispark shield or a littlewire 2x3 pin device to plug in so I could do tests on it before each rubygem update!
I agree it would be pretty neat to get the nunchuck working.
It's encrypted? Is it i2c compliant or a little bit broken? Do you think it'd work with littlewire @kehribar?
Here is an example of arduino<-> wii nunchuck communication http://www.windmeadow.com/node/42
Note the function:
void
nunchuck_init ()
{
Wire.beginTransmission (0x52); // transmit to device 0x52
Wire.send (0x40); // sends memory address
Wire.send (0x00); // sends sent a zero.
Wire.endTransmission (); // stop transmitting
}
We need to be able to send just these 2 bytes, in order to tell the nunchuck to send its data in the normal 'unencrypted' way. This is referring to the bytes being sent on i2c, not i2c itself.
Hi,
Please see my this comment: https://github.com/Bluebie/littlewire.rb/issues/4#issuecomment-24293704
Best, ihsan.
Seems that the littlewire.rb needs to use different i2c entrypoints then?
I'm confused. The littlewire.rb library does not have a 'send' method. It has write, but the write method does take a variable length input, up to four bytes as far as I can see, but with no minimum. Isn't this what you want? Does it not work?
wire = LittleWire.connect
wire.i2c.start 0x52, :out
wire.i2c.write [0x40, 0x00], true
I've committed a couple of little bugfixes including the other issue you started. Maybe download the i2c.rb file and try now?
When I call i2c.write with [64, 0], I get this error:
NoMethodError: undefined method <<' for nil:NilClass /home/ron/.rvm/gems/ruby-2.0.0-p247@artoo-digispark/gems/littlewire-0.9.7/lib/i2c.rb:35:in
write'
try it now? it doesn't cause exceptions for me now when I run my code from above, but I don't have an i2c device connected. I need to go soon - things to do today, but if you show me how to wire this thing up to a nunchuck we can try and get this working perhaps tomorrow. Make things easy for me. I don't want to read through a bunch of articles to figure out how to do it. Let me know if it's working and I should be able to push a new rubygem in a few hours.
Thanks for the update. I can call write now without error. However, when I pass in [64, 0] isn't that code actually sending [64, 0, 0, 0] to the littlewire i2c write routine?
As far as how to wire it, the pin connections are as follows: GND & +5, then the 2 data connect with 4.7k resistors inline Digispark P0 → SDA Digispark P2 → SCL
The I2C Address is 0x52
This has a couple decent pictures http://digistump.com/wiki/digispark/tutorials/nunchuck
The USB specification does not allow wValue and wIndex to be of variable length, so yes, technically it does pass 64, 0, 0, 0, to the littlewire, but it also passes the length of the request in bytes bRequest: 0xE0 | slice.length | ((stop ? 1 : 0) << 3),
packed in to three bits of the 16-bit bRequest number. LittleWire should interpret that correctly to only pay attention to the first two bytes.
Doesn't i2c require pullup resistors? or are those built in to the nunchuck?
Using with an arduino uno I do not need the pullup resistors. I tried both with and without on digispark, but no difference.
You are using a digispark? Do the digitstump examples work, like the joystick one
On 12 Sep 2013, at 5:25 pm, Ron Evans notifications@github.com wrote:
Using with an arduino uno I do not need the pullup resistors. I tried both with and without on digispark, but no difference.
— Reply to this email directly or view it on GitHub.
The other code I use with littlewire all seems to work, FWIW. Just not the i2c... yet :)
Hi,
i2c definitely needs pullup resistors.
Arduino library uses internal weak (~100kOhm) pullup resistors and it kinda works at small distances. But the i2c library in the littlewire have no such feature. You need to provide ~4.7 kOhm resistors for SDA and SCL lines.
By the way,
If you have a scope / logic analyser at hand, you can check the signals. You might be using wrong pins?
Best, ihsan.
Which pins on the digispark should I be using? I currently have nunchuk data going to p0, and clock to p2, plus pullups 4.7k for both.
Yes they are true.
I have the correct circuit, as it works with my arduino/firmata code. SO either I am calling it wrong, or perhaps the littlewire.rb lib is passing extra bytes to digispark device, which is perhaps passing them along to the nunchuck, even zero bytes?
My call to the littlewire i2c read, is always returning "\xFF\xFF\xFF\xFF\xFF\xFF"
, which is what made me think the correct bytes were not being sent to the wii nunchuck. In the case that the init bytes are not being sent, the device will return all 0xFF's
@Bluebie if it would help, we'd be willing to send you a digispark and nunchucky adaptor, so you can actually test this out. My email is ron at hybridgroup dot com if you want to send me your shipping address.
Thanks for the help @Bluebie & @kehribar we appreciate it!
Hi,
You should init the I2C support at the littlewire and also set a small delay for the bitbang I2C routines. I don't know whether is there any ruby equivalent of those functions but below you can find how it is done in the C library. Take a look at line #40 and #41
https://github.com/littlewire/Little-Wire/blob/master/software/examples/i2c_blinkM.c#L40
Best, ihsan.
Sorry I use "init" incorrectly. What I meant, was once the i2c bus has been initialized, the sending of the bytes to the wii, that cause it to start sending valid data:
void
nunchuck_init ()
{
Wire.beginTransmission (0x52); // transmit to device 0x52
Wire.send (0x40); // sends memory address
Wire.send (0x00); // sends sent a zero.
Wire.endTransmission (); // stop transmitting
}
Have you seen the snipped I've sent you?
You should initialize the i2c support at the littlewire by sending a command to it. Are you doing it? Also you should tweak with the delay parameter. I don't know about the ruby library's implementation but I've sent you how I do it in the standard C library.
ihsan.
@Bluebie is already doing the i2c_init here: https://github.com/Bluebie/littlewire.rb/blob/master/lib/i2c.rb#L4
Let me experiment with the delay param, I bet that is not being set...
OK, I am finally getting data! The problem was indeed that the delay param needed to be set to 0 for the wii nunchuck to be happy. I think with the other fixes that @Bluebie already comitted to littlewire.rb plus some documentation improvements, we might be good.
Can you tell me about this delay? delay where? I ordered a nunchuck socket from ebay which should arrive in a week or so, and I already have the resistors, so I'll be able to build this circuit then. If you can show me which code is needed I can add it to the library, and if you show me some example code of reading data from the nunchuck I'll add a WiiNunchuck class to the littlewire ruby library so people don't need to mess around with direct communication, and can just talk to these things without any fuss.
littlewire.i2c.delay = 0
OK I was not getting valid data after all :(
Still digging in, but when @Bluebie gets the correct hardware, you will have a better chance of figuring this out then.
Wait when did it become my job?
On 13 Sep 2013, at 10:58 am, Ron Evans notifications@github.com wrote:
OK I was not getting valid data after all :(
Still digging in, but when @Bluebie gets the correct hardware, you will have a better chance of figuring this out then.
— Reply to this email directly or view it on GitHub.
Please oh please, oh mighty @Bluebie I will keep trying to figure it out, but I defer to your great knowledge of littlewire.
I've gotten wii controllers (both nunchuck and classic) working with firmata, using artoo code:
https://github.com/hybridgroup/artoo-i2c/blob/master/lib/artoo/drivers/wiidriver.rb#L21
is the core of what we are doing. How can I achieve that using littlewire.rb?
Well I wired up a littlewire to a nunchuck (not nintendo official, a third party one) and I sure can't get it to work. It doesn't seem to react at all - I only ever read six bytes of 0xFF, which seems very wrong, because I also get that result when I unplug the nunchuck!
So yeah, I continue to not know how to debug I2C or really have any idea how the protocol is even supposed to work, but my translating of arduino and pic code in to ruby has been a total failure. This is very confusing, because every piece of code I have found shows an entirely different set of instructions for the initialization and some even use different instructions for the actual device communication. Some address it as 0x52, some as 0xA4 and 0xA5. In summary I have no idea what is going on, but I've broken one of my nunchucks plugs and ended up soldering it straight on to a littlewire connector, so I'd like to get this thing actually working so it wasn't a complete waste. I really have no idea what to do at this point though.
I have verified however that the nunchuck is working. I've tried some of the digispark examples and those do work, so whatever isn't working about my littlewire ruby library is something in the littlewire firmware, or in the ruby code.
Hi All,
Best way to debug I2C signals is using a logic analyser. The best one in terms of price/software quality is the Saleae Logic analyser.
Jenna, can you convert this part of this program into ruby? https://github.com/littlewire/Little-Wire/blob/master/software/examples/i2c_blinkM.c#L45 This is basically sends a I2C start command to a spesific address and checks whether the system received a ACK or not. This way, you can search the entire I2C bus for several different devices. This should give better test procedure. Only one device should appear at your search result with a single nunchuk, if not there's a problem. Or you can directly try the C example?
I2C device Address values are actually 7 bit. We shift that address to 1 bit left and add a LSB to the resulted 8 bit address which represent a READ/WRITE operation. That should clarify the different addressing conventions :)
Best, ihsan.
Well,
I connected my original Wii nunchuk via couple of jumper cable to breadboard. Added two pullup resistors and connected to my Little Wire hardware. Firmware version is v1.2
When I execute the i2c_blinkM example I'm getting:
> Little Wire firmware version: 1.2
> Address search ...
> Found device at 82
82 is equivalent to the 0x52 hex address. I haven't tried adding button, accelerometer reading features but this would be a small proof-of-concept for the I2C support.
By the way I'm using 10 as delay parameter. And Jenna, this delay is used in the software bitbang I2C signals in the littlewire hardware.
I'm probably write a i2c_nunchuck example for the Little Wire C library.
Best, ihsan.
Well i2c works somewhat now. I implemented a little abstraction for the Digispark EEPROM shield. It reads and writes bytes from that device successfully over i2c, so the i2c library is starting to get in to a usable shape. https://github.com/Bluebie/littlewire.rb/blob/master/examples/i2c/digispark-eeprom-kit.rb
Still nunchucks don't work though. I'm boggled by it. Any ideas?
@kehribar I've converted the i2c bus scanning part of the blinkm example in to ruby and included it in the library, so littlewire.i2c.scan returns an array of addresses. It works quite well, but I had to do some bug fixes to get it working. Spent a couple of hours tonight just staring at code side by side trying to pick out the bugs. There were a bunch of places where I was transmitting bits inverted because I had made bad assumptions about the littlewire hardware api. I don't have any blinkm devices to test with, so I mainly just have some digispark things. I think I have an i2c port expander digispark shield also, which might be another thing worth implementing an abstraction for as a way of finding any more bugs, and also because it sure seems like a lot of littlewire users nowdays are using it on digispark devices.
Hi,
I'm finally getting some data out of Nunchuck over Little Wire via C library.
I've done bunch of modifications to the library and the firmware, but I'm not sure which of them were actually necessary. I'm off to sleep and will check them at the morning. I hope I can leave the firmware intact, but I'm not sure.
just letting you know :)
Best, ihsan.
Awesome @kehribar I look forward to it!
I pushed the latest changes to the v1.3_betawork branch of the main Little Wire repo. https://github.com/littlewire/Little-Wire/tree/v1.3_betawork I had to modify both the littlewire.c library file and the firmware.
If you can't compile, but you should be, the v1.3 firmware ; let me know so that I can upload the binary somewhere.
Nunchuck example is here: https://github.com/littlewire/Little-Wire/blob/v1.3_betawork/software/examples/i2c_nunchuck.c
Best, ihsan.
I'm playing around with the beta now. For whatever reason your example i2c_nunchuck finds two items on my i2c bus, 82 and 91. Weird. I'm using a non-nintendo branded nunchuck though. Continuing to poke around. In the mean time the littlewire ruby library sure is getting a lot of nice new features. Pretty handy for testing: In the next rubygem it installs a system wide command line utility called 'littlewire.rb' which you can use to switch between versions like this: littlewire.rb install 1.0
or littlewire.rb install cdc232
. For now i'm shipping the hex files for all these versions built in to the rubygem, but maybe there will be a better way some day. I want to also add some other features to this command line tool, like the ability to issue wiring-style commands - digitalWrite, pinMode, etc... so you can just change things one at a time for experimentation. I think an analog logger would also be cool, if it made a little graph on the command line like an ASCII oscilloscope or something like that!
Great Work @kehribar! I ported a version of the arduino code which works with third party controllers as well as nintendo ones, and I have now included a nunchuck abstraction right there inside littlewire.rb! To use it in your program, require 'littlewire' as usual, but also require 'littlewire/gadgets/nunchuck'. Then you can call wire.nunchuck.sample to read the controller, and the resulting object contains .accelerometer and .joystick properties with .x, .y, and .z properties (no z on joystick tho), and a .buttons property with .c and .z properties. I've included an example in the examples folder for how you can use this code.
I highly recommend you try it out as soon as you have time. gem install littlewire
to get the update, then install the littlewire 1.3 beta on to a digispark or micronucleus bootloaded littlewire using littlewire.rb install latest-beta
and plugging in the device when it asks. Once the firmware is updated, try my example code by running littlewire.rb racer
with a nunchuck connected. I suggest you don't read the example code till after you've tried it. Let me know what you think, or if there's any ways I could improve this!
BTW you can now cleanly shift between littlewire versions with that install command. You can install 1.2, 1.1, 1.0, latest, latest-beta, cdc232, and probably there will be many more in the future. So no more trying to find hex files and the micronucleus program. Finally littlewire is becoming even more the swiss army knife I always wanted it to be by throwing off the shackles of trying to implement everything inside 6kb! The littlewire library includes a pure ruby implementation of a micronucleus uploader app, so no compiling or extra dependancies are needed for this feature, but on some platforms you might need to run the command with sudo or install micronucleus drivers (I'm looking at you, Windows!).
So excited to hear what you think of the latest update.
Hi Jenna,
I'm getting an error when I try to test the littlewire.rb. I also had to install the thor externally via gem install thor.
I'm on xubuntu netbook machine at the moment.
kehribar@kehribar-1008P:~$ sudo littlewire.rb racer
/var/lib/gems/1.9.1/gems/littlewire-0.9.8/bin/littlewire.rb:74:in `racer': undefined local variable or method `__dir__' for #<LittleWireUtility:0x8e1fbc4> (NameError)
from /var/lib/gems/1.9.1/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
from /var/lib/gems/1.9.1/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
from /var/lib/gems/1.9.1/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
from /var/lib/gems/1.9.1/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
from /var/lib/gems/1.9.1/gems/littlewire-0.9.8/bin/littlewire.rb:78:in `<top (required)>'
from /usr/local/bin/littlewire.rb:19:in `load'
from /usr/local/bin/littlewire.rb:19:in `<main>'
kehribar@kehribar-1008P:~$ sudo littlewire.rb
Commands:
littlewire.rb firmwares # List all versions which can be installed via install command
littlewire.rb help [COMMAND] # Describe available commands or one specific command
littlewire.rb install [version] # Install a specific firmware on to the littlewire device
littlewire.rb racer # Attach a Wii Nunchuck and play a game
littlewire.rb version # Which version of the ruby library is this?
Best, ihsan.
Try installing the new 0.9.9. Looks like a couple of bugs where I accidentally used features which were only added in ruby 2.0, as well as forgetting thor. Should be all good now hopefully. Also, do try without sudo first. It is just the way I lazily bypass usb userspace permissions when I use linux. The propper way is to install those weird permissions files, but it maybe isn't even necessary. I just know some people including myself have had a bit of trouble with digiusb needing special permissions changes to work on linux outside of the root user.
Does it work now? :smile:
Nope. It's still not working. This is an output from a newly installed machine. I just installed ruby1.1-full package and littlewire gem.
kehribar@crunchbang-k:~$ littlewire.rb race
/var/lib/gems/1.9.1/gems/littlewire-0.9.9/bin/littlewire.rb:9:in `<class:LittleWireUtility>': undefined method `pathname' for File:Class (NoMethodError)
from /var/lib/gems/1.9.1/gems/littlewire-0.9.9/bin/littlewire.rb:7:in `<top (required)>'
from /usr/local/bin/littlewire.rb:23:in `load'
from /usr/local/bin/littlewire.rb:23:in `<main>'
kehribar@crunchbang-k:~$ littlewire.rb
/var/lib/gems/1.9.1/gems/littlewire-0.9.9/bin/littlewire.rb:9:in `<class:LittleWireUtility>': undefined method `pathname' for File:Class (NoMethodError)
from /var/lib/gems/1.9.1/gems/littlewire-0.9.9/bin/littlewire.rb:7:in `<top (required)>'
from /usr/local/bin/littlewire.rb:23:in `load'
from /usr/local/bin/littlewire.rb:23:in `<main>'
I was unable to update any of my digisparks with the latest-beta firmware:
$ littlewire.rb install latest-beta
Will upload to a littlewire which has been updated with the micronucleus bootloader, or to a digispark.
Plug in micronucleus device now: (waiting)
Attached to device: <Micronucleus 1.02: 5.9 kb programmable>
Writing program in to device's memory
/home/ron/.rvm/gems/ruby-2.0.0-p0/gems/littlewire-0.9.8/lib/littlewire/gadgets/micronucleus.rb:57:in `program=': Program too long! (RuntimeError)
from /home/ron/.rvm/gems/ruby-2.0.0-p0/gems/littlewire-0.9.8/bin/littlewire.rb:28:in `install'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/gems/littlewire-0.9.8/bin/littlewire.rb:78:in `<top (required)>'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/bin/littlewire.rb:23:in `load'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/bin/littlewire.rb:23:in `<main>'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
from /home/ron/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'
Good news: I figured out I needed to update to newer micronucleus
Bad news: appears I bricked one of my digisparks by installing micronucleus-1.06-jumper-v2-upgrade.hex
on it in error
Good news: I figured out to actually use micronucleus-1.06-upgrade.hex
and was then able to install 'latest-beta` on a different digispark
Bad news: still no data appearing from my wii nunchuck.
@deadprogram do you understand that when you use -jumper you need to connect the d5 pin to ground via a wire or resistor or button or something, and keep it connected while you plug the digispark in to the computer, to enable programming mode? Jumper disables the bootloader unless that wire is connected, so the user program launches immediately. I will be very surprised if the digispark is actually bricked. Perhaps before the next beta is released ihsan can figure out how to get the firmware a tiny bit smaller so it fits in unmodified digisparks.
@ihsan your pathname comment is totally valid. Of course it is called dirname! Fixed now, if you update the rubygem. Do you mean ruby1.9.1-full? Ruby 1.1 will not work! It is too old!!
@deadprogram no data appearing? even for my racer demo? try adding these two lines:
wire.nunchuck
wire.i2c.delay = 10
after this on line 8 of examples/i2c/nunchuck.rb
raise "No LittleWire device connected" unless wire
Experiment with different delays. Maybe one of them will work!
Hi Jenna,
I meant 1.9.1 of course :) That was a typo.
Your new rubygem release installs and runs without dependency problems.
But I tried firmware update feature on Linux machine and It didn't work. Gave couple of libusb IO errors. I tried with sudo and the result was the same. For the nunchuck i2c the same hardware and firmware acts very differently on my linux netbook and main mac. And even it acts differently on ruby library / C library. Ruby library always give 'i2c device unresponsive' error but C library works OK on mac but not on Linux netbook. The weird thing is blinkM example works OK in both MAC and linux.
I guess there are some intermittent bugs in somewhere but I'm not sure.
I'm taking some time off from this issue. I hope to return to investigate more.
Best, ihsan.
Mmm yeah. I've actually found it less reliable when I plug it in to a different mac running the same operating system! Crazy! Maybe the nunchuck is sensitive to timing or power supply? I can presume most (all?) of us are running the nunchucks on 5v despite them being designed for 3.3v
Bluebie
On Sunday, 15 September 2013 at 9:43 PM, kehribar wrote:
Hi Jenna, I meant 1.9.1 of course :) That was a typo. Your new rubygem release installs and runs without dependency problems.
But I tried firmware update feature on Linux machine and It didn't work. Gave couple of libusb IO errors. I tried with sudo and the result was the same. For the nunchuck i2c the same hardware and firmware acts very differently on my linux netbook and main mac. And even it acts differently on ruby library / C library. Ruby library always give 'i2c device unresponsive' error but C library works OK on mac but not on Linux netbook. The weird thing is blinkM example works OK in both MAC and linux.
I guess there are some intermittent bugs in somewhere but I'm not sure. I'm taking some time off from this issue. I hope to return to investigate more. Best, ihsan.— Reply to this email directly or view it on GitHub (https://github.com/Bluebie/littlewire.rb/issues/5#issuecomment-24470008).
Last night, I was able to get my nunchuck working twice with the littlewire.rb gem and my Artoo adaptor, however, was not consistent: it worked a couple times, but after a restart was not working anymore. Super weird!
Note that I am able to use the nunchuck with no problem on my arduino with our firmata adaptor, when running at 5V.
After playing around a bit, I realized my pullup resistors were wired in a little wonky. The digispark is very sensitive to this. Anyhow, I now have my own code working to receive joystick data, although I do get all FF's periodically, that might be my old breadboard.
Now, I am looking further, to see why I am not getting button data. That appears to be why the new littlewire racer sample runs but does not work for me, as it waits for a button even that never arrives.
More soon...
I am also getting all 0xFF's periodically. After about 20 seconds or so, but it appears to depend partially on which computer I'm using. Pretty odd.
@Bluebie could I please request you include the latest micronucleus firmware .hex files along with your other .hex files? It would be really useful for people who want to update their current firmware!
Are you not using a digispark? You can update to the latest micronucleus using the digispark arduino program by going to the Tools menu, and selecting Burn Bootloader, then plugging in your digispark. This also works for adding micronucleus to blank chips.
I am trying to make this work entirely from command line for artoo users, so our command line tools call yours to perform all needed installs, for example artoo install digispark micronucleus
would call your 'littlewire.rb install micronucleuscommand, and then
artoo install digispark littlewirecould call your 'littlewire.rb install latest-beta
command.
The current I2C#send has no way to send arrays of less than 4 bytes length.
In order to properly use devices that send encrypted data, such as the Wii nunchuck, you need to be able to send messages of 1 and 2 bytes length.