wemos / WEMOS_Motor_Shield_Arduino_Library

Arduino library for the WEMOS Motor Shiled - a shield for D1 mini, i2c interface, based TB6612
36 stars 32 forks source link

What is the I²C chip on this board? #1

Closed deshipu closed 7 years ago

deshipu commented 8 years ago

The TB6612 chip listed on the schematic and in the comments is just a motor driver chip. There is a second chip on this board, providing the I²C communications and PWM generation -- however, it's unlabeled on the schematic.

I'm trying to write a library for interfacing with this shield for the MicroPython on ESP8266, and it would be a great help if you could tell me what the chip is, so that I can check its datasheet for details (I don't want to just blindly copy from the Arduino library, but if anything else fails, I will have to do it).

I have ordered this shield, and I could just wait for it to arrive and then check the markings on the chip, but it takes a long time to arrive, and I thought that I could start writing the library for it already.

Thank you for the great board and great shields!

deshipu commented 8 years ago

The shield arrived, and I see the chip is just a microcontroller. Is the program running on the microcontroller available somewhere, or at least a documentation for all the commands it accepts over i2c?

mcauser commented 8 years ago

The motor driver is TB6612FNG and cpu is STM32F0 series.

I haven't seen any further documentation other than this repo. @wemos could you publish the source code that you flashed to the STM32 chips?

Thinking about flashing MicroPython onto the STM32F0? It may not fit with such little ram. http://forum.micropython.org/viewtopic.php?f=12&t=894&p=5220&hilit=STM32F0#p5220

deshipu commented 8 years ago

No, no, micropython would be on the esp8266, I just want to know the i2c commands.

mcauser commented 8 years ago

I know, but... why not both? 🍰

mcauser commented 8 years ago

Wire.write() commands in here list the known options: https://github.com/wemos/WEMOS_Motor_Shield_Arduino_Library/blob/master/src/WEMOS_Motor.cpp

Waiting on WeMos pushing the full source code so we can see if there are any extra ones hiding in there.

mcauser commented 8 years ago

Mine are labelled STM32F030F4P6.

From the datasheet: 32bit ARM Cortex M0 Microcontroller, 48MHz, 16 kB Flash, 4kB SRAM, TSSOP20. 1x advanced control 16-bit timer, 4x general purpose 16-bit timers, 1x SPI, 1x I2C, 1x USART, 1x 12bit ADC, 15 GPIOs, 2.4-3.6V

deshipu commented 8 years ago

I wonder, did it work with this arduino library? Because mine didn't -- it pulls the I2C clock line down as soon as it receives its address, and keeps it like that until reset, preventing any communication.

deshipu commented 8 years ago

The top two lines is doing i2c.scan(), you can see it pulls down SCL as soon as it gets its address. The middle two lines are i2c.scan() with some other i2c device. The bottom two lines is a close-up of the moment it pulls the line down. i2cmotor

mcauser commented 8 years ago

I noticed that too. Library works fine on Arduino until you perform a scan, then it disappears.

The protocol is pretty straight forward.

First you have to set the frequency, eg. 16000 for 16khz. write bytes [0,0,62,128] to 0x60 (62<<8)+128 == 16000 0x60 = device addr (0x30) << 1

Next you send a command [motor,direction,duty msb,duty lsb] eg. spin motor a, clockwise, 34.5%, write [16,2,13,122] to 0x60

Motor: a = 16 (0 | 0x10) b = 17 (0 | 0x10)

Direction: short break(?) = 0 counter clockwise = 1 clockwise = 2 stop = 3 standby = 4

Duty: duty *= 100, eg. 34.5% -> 3450 3450>>8 == 13 3450 & 0xFF = 122 msb = 13, lsb = 122

To stop motor a, write [16,3,39,16] The default duty is 100% or 10000. 10000>>8 == 39 10000 & 0xFF == 16

mcauser commented 8 years ago

These all work fine on my WeMos D1 mini running Arduino but I couldn't get them working in MicroPython. Here's what I tried.

from machine import Pin, I2C
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
i2c.start()

setfreq=bytearray([0,0,62,128])
i2c.writeto(0x60, setfreq)

motora30=bytearray([16,2,11,184])
i2c.writeto(0x60, motora30)

motorastop=bytearray([16,3,39,16])
i2c.writeto(0x60, motorastop)

i2c.start()
i2c.write(b'\x60')
i2c.write(b'\x10')
i2c.write(b'\x02')
i2c.write(b'\x0B')
i2c.write(b'\xB8')
i2c.stop()
deshipu commented 8 years ago

Well, I tried that, didn't work for me: https://bitbucket.org/thesheep/micropython-d1motor/src/5cb93370cd84417391a9af5d8f4b4ea75de43a61/d1motor.py

deshipu commented 8 years ago

Setting the frequency is especially mysterious to me. You say I should send a 0 there, but the Arduino code actually does:

    Wire.write(((byte)(freq >> 16)) & (byte)0x0f);
    Wire.write((byte)(freq >> 16));
    Wire.write((byte)(freq >> 8));
    Wire.write((byte)freq);

which means it first sends the lower 4 bits of the most significant byte, then the whole most significant byte, then the middle byte, and then the least significant byte (apparently frequency is 24bit?). This makes little sense to me...

deshipu commented 8 years ago

Hmm, following your example and sending two zeroes as the first bytes makes it work -- but only sometimes. Sooner or later the chip gets into the "fuck you" mode.

mcauser commented 8 years ago

Lol yeah. Sounds like the firmware could use some love.

I also noticed that it sometimes doesn't work on cold boot unless the motors V and G connected to a power source.

I think the first freq>>16 should be >>24. But the driver only supports up to 100K, so not sure about that one. Perhaps rushed copy n pasted code.

deshipu commented 8 years ago

I think that the first freq>>16 should actually be 0x00|_motor, since the motors are supposed to have independent pwm frequencies... If the source code was made available, we could work on improving it...

johnrichardrinehart commented 7 years ago

@deshipu and @mcauser, to revive this thread. I think that WeMOS did open source the firmware.

Check out this: https://github.com/wemos/Motor_Shield_Firmware .

deshipu commented 7 years ago

Yes, they did. And I since figured out how to reprogram the shield without an stlink programmer, with just a serial to usb dongle, and had someone re-write the firmware completely, so that it works reliably. See https://hackaday.io/project/18439-motor-shield-reprogramming

johnrichardrinehart commented 7 years ago

That's awesome. Thanks for the link. I look forward to flashing some better firmware to that little guy.