Closed deshipu closed 7 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?
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
No, no, micropython would be on the esp8266, I just want to know the i2c commands.
I know, but... why not both? 🍰
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.
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
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.
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.
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
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()
Well, I tried that, didn't work for me: https://bitbucket.org/thesheep/micropython-d1motor/src/5cb93370cd84417391a9af5d8f4b4ea75de43a61/d1motor.py
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...
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.
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.
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...
@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 .
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
That's awesome. Thanks for the link. I look forward to flashing some better firmware to that little guy.
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!