-
Notifications
You must be signed in to change notification settings - Fork 1
Ammeter
The ammeters on the robot are paramount to success in full autonomy.
The ammeters consist of custom designed PCBs with an INA219 IC as the current measuring device.
The INA219 communicates with the robot's computer using the I2C communication protocol.
If you've looked up the INA219, you've certainly seen lots of breakout boards. One of the most popular ones is surely the Adafruit one, but there are plenty of others too. You may also notice that they can be had a for a reasonable price and are much more compact than the one that we have. So why did we go through the effort to make our own custom PCBs to house the INA219 which is also much larger than the other breakout boards? Well, it's all because of current. The Adafruit board only supports 3.2A max which is nowhere near enough for our motors. You might also be wondering what limits the ampacity of these boards. It is two things: one is the shunt resistor on it and two is the size of the traces. Shunt resistors are designed to have very low yet precisely known resistances to enable current measuring with minimal voltage loss, but they have power limits due to how much they can heat up. Similarly, PCB traces, though the have very low resistance due to the fact that they are just copper, they have some amount of resistance and can get very hot if they are not thick enough. As such, our custom PCBs feature three key changes to mitigate these issues: one is the thicccc traces, two is the 2512 resistor (basically, its a big boi resistor to handle lots of current), three is high-current Molex Sabre power connectors integrated directly. All of these combine to allow our PCBs to theoretically handle 30+ amps of current! I don't know if the future team will find a use for such copious amounts of ampacity, but you have it if you want it 😄... Otherwise, you can just throw away years of hard work and pick up an Adafruit one if you don't 😭 (Guess Alex is in a cheeky/sarcastic mood rn)
All of the following information can be found in the datasheet of the INA219.
The first thing to note is the address of the INA219. This is controlled by which line the A0 and A1 pins are connected to (GND, V+, SDA, or SCL). These are set on the PCB by the set of 8 (4x2) resistor pads. They are labeled on the silk screen as to which is which. Solder two 0603 jumpers (one in the left column (A0), one in the right (A1)) to the appropriate pads (V+, GND, SDA, SCL from top to bottom) to set the address.
Now you can either set the address or at least tell what it is set to 🙂
The INA219 bases its reading by measuring the voltage differential across our shunt resistor.
Since it is a 1mOhm resistor with a 2W rating, it should handle up to 44A! (The PCB traces and Sabre connectors are close to 30A max though)
#TODO implement good practice bypass caps and pullup resistors... Hey I was never taught this stuff, I had to learn it on my own so I don't want to hear it 😠
In any case, you will probably want to program the INA219 in order to fit your specifications. This will allow you to tune the INA219 for precision or range (i.e. very precise voltage/current measurements or support for larger voltage/current values at the expense of some precision)
See page 12 of the datasheet for the programming section. Here are some numbers based off of a max expected current of ~33A and our Rshunt of 1mOhm:
Current_LSB = 0.001A (this is a close approximation for simplicity. This means the INA219 will be precise down to 1mA. This also means that the current register will already read as mA!)
Cal = 40960 (This is the Calibration Register's contents then!) (Place this value in the calibration register which is address 0x05)
Power_LSB = 0.02W (This means the INA219 will be precise down to 20mW. To convert to mW, just multiply by 20. Or divide by 50 to get to W.)
It is worth noting that "These registers are volatile,and if programmed to other than default values, must be re-programmed at every device power-up".
Also, note that the Cal value which is placed in the Calibration Register is in binary of course, so 40960 would be 1010 0000 0000 0000. This is the value you will put in the calibration register if you want a 1mA precision with a FSR of ~33A.
Cool! With that done, now you're set... I mean, that is, you have the value you need to program but you still need to figure out how to actually write to the darn thing... So yeah, uh, good luck figuring that out!
Just kidding, I just realized it's all under 8.5.6 🙂
The following page (two pages after the start of 8.5.6) also contains a timing diagram for writing a word and reading a word if you're interested.
In any case, you just need to know which register you want to read/write from/to. There are only five registers with addresses 1-5 and only two of them can be written to so it isn't too hard. You can check out all that info under 8.6. The configuration register can set some interesting stuff if you're interested.
So yeah, if you want to write that 40960 to the Calibration Register of an INA219 with an address of 69 (Nice) (This would be V+ on both A0 and A1 btw), it would look like this:
0100 0101 0(ack) 00000101 (ack) 10100000 (ack) 00000000 (ack)
Address W Reg Addr first 8 next 8
Note that every (ack) is the bit where the INA219 acknowledges that it has received data. This should be pulled low by the INA219.
Note that you should create a START condition before sending data and a STOP condition after
Start condition: Pull SDA from high to low while SCL is high.
Stop condition: Pull SDA from low to high while SCL is high.
Awesome, now you're set. Oh, except for reading from a register. Figure 16 shows that reading a register does not consist of sending a pointer address, so how do you read a register? See Figure 18. You start a write operation but end it after sending the register pointer. Once that register pointer is sent, that will be the register that is read from when you perform a read operation. In other words, if you want to keep reading current, you only have to set the register pointer once and then you can just queue up read operations by sending the address of the INA219 without needing to worry about the address of the current register.
Good luck!