1) Home - Skidude88/Skidude88-G29-PS4-LoadCell-Arduino GitHub Wiki
Welcome to the Skidude88-G29-PS4-LoadCell-Arduino wiki!
-
Arduino Pro Micro - Ideally 3.3v version. This project Initially used the 5v version board as a "proof of theory". Then a 5v Board with the USB broken off, running the sketch at 3.3v 8Khz - The 5v versions are approx £3 on Ebay (China). The 3.3v versions are more.
-
'Bathroom Scales' style Load Cell(s)
-
Load Cell Amplifier : HX711
4x Load Cells and HX711 Bundle, Approx £3 on Ebay (China)
- Low Pass Filter:
- 1x Resistor
- 1x Capacitor
or Instead of Low Pass filter
- MCP4725 - DAC board - Approx £2 on Ebay (China)
For single load cell configuration:
- 2x 1k resistors
-
A Mate with a 3D printer (& beers for them)
-
CAD design - see main GeekyDeaks project https://github.com/GeekyDeaks/g29-load-cell.
Input Pins (from Load Cells):
E+ (Excite +)
E- (Excite -)
A+ (Amplifier/Output + Channel A)
A- (Amplifier/Output - Channel A)
B+ (Amplifier/Output + Channel B) - Not used for this project
B- (Amplifier/Output - Channel B) - Not used for this project
Output Pins:
SCK - Clock
DAT - Data
Other:
Vcc/Gnd - Power/Ground
The HX711 board can run at either 10Hz (By default) or 80Hz. Some boards have a select jumper to solder/break track to change the Freq. To achieve 80Hz without this selector (on cheaper version boards) the Rate pin requires +v. Cut the track directly next to pin15 "Rate" (Some forum posts needlessly go to the trouble of lifting pin15 off the board!) and then solder pin15 to pin16 (Vcc) directly above.
Arduino IDE (Desktop) v1.8.10 https://www.arduino.cc/en/main/software
Initially 2x 3 wire load cells were used, each being half of a Wheatstone Bridge
See CAD "Dual_Holder" & "Dual_Spacer" by GeekyDeaks.
LoadCell#1 - White wire, Connect to LoadCell#2 - Black wire
LoadCell#2 - White wire, Connect to LoadCell#1 - Black wire
These are E+ & E-
Then the remaining 2x red wires are A+ & A-
The HX711 has two channels, A & B, this project is using A, so connect to A+ & A-
Note for the Arduino sketch file:
The hx711.h library file details the .begin command having a gain parameter. If not specified, a default of 128 is used : Channel A
// Initialize library with data output pin, clock input pin and gain factor.
// Channel selection is made by passing the appropriate gain:
// - With a gain factor of 64 or 128, channel A is selected
// - With a gain factor of 32, channel B is selected
// The library default is "128" (Channel A).
void begin(byte dout, byte pd_sck, byte gain = 128);
If the load cell doesn't perform as expected, switch around either: A+ with A- (red wires) or E+ with E-. (Either option is doing the same thing).
HX711 library file used : HX711-0.7.3.zip ( I can't recall where I got this - possibly https://github.com/bogde/HX711/releases)
Useful Info:
https://www.instructables.com/id/How-to-Interface-HX711-Balance-Module-With-Load-Ce/
One of the 3 wire load cells (previously mentioned above) is replaced by 2x 1K resistors to complete the 2nd half of the Wheatstone Bridge.
See CAD "Single_Holder" by GeekyDeaks.
Useful Info: Step 2 on the link below shows the relevant connections between the remaining loadcell and resistors.
https://www.instructables.com/id/Tutorial-to-Interface-HX711-With-Load-Cell-Straigh/
https://github.com/jstoezel/brake_pedal_beam_load_cell
Pedal off = 3.1v *see summer update
Pedal on 100% = 1.9v *see summer update
Summer 2020 update - I've investigated these values, they seem to be a bit off. See wiki page 3.3v Pro Micro and G29
Supplying PWM signal direct to the G29 (pin9) from the Pro Micro didn't work, so a basic passive low pass filter was added. Consisting of :
1x 2.2uF Capacitor & 1x 4.7k resistor
The pedal then operated OK and is usable. However, visually, it is noted that there is flicker on the brake pedal travel. This is work in progress to improve/resolve. Will investigate the use of a DAC board (MCP4725) in place of the Low pass filter or running the PWM Timer frequency faster or changing the LPF component values.
Useful info:
https://provideyourown.com/2011/analogwrite-convert-pwm-to-voltage/
Requires USB power,so useful to have a PC close to Pedals for (programming and power)
Use any of the Data pins to receive the HX711 CLK and Data signals (any two of the 18 "Blue" pins on link below). Originally in this project pin15 was used for Data, pin14 for CLK.
https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro
The get_value data received from the HX711 to pin15, when pressing down really hard on the Load cell(s) is the magnitude of 1,000,000. To make things easier - an arbitrary scalar of 1100 was used.
Use any of the 5x PWM pins to output the PWM "voltage" out to the low pass filter (any of the 5 "red tick" pins on the link above). Originally this project used pin10 & timer1.
It was determined that PWM(255) wasn't 5v,it was 4.7v (Pro Micro Voltage drop due to onboard circuitry). This resulted in calculations being base as
3.1v - PWM(163) - 0% Brake Pedal
1.9v - PWM(103) - 100% Brake Pedal
With a 3.3v supply (from G29 Pedal) figures will be around:
PWM(240),94.1% DutyCycle = 3.1v
PWM(147), 57.6% DutyCycle = 1.9v
Note: be careful of the USB connector, Unfortunately it doesn't take much to knock it off.
Code: (5v USB): Code/SimPedal_pwm_ver3.ino (Can't figure out how to link on here)
With just pedals connected up to the HX711 and Pro Micro, the LPF (at pedal rest/off), is kicking out 3.1v due to analogWrite(168).
Previously, running with two load cells and a LPF - there were no issues, other than flicker of the brake application.
The sketch code, after arbitrary scaling was applied was reading, from the hx711, on full brake, around 700-900 (before being inverted).
Now, with one load cell and the same sketch and scaling, the hx711 is now reading 1000-1500 (before being inverted) with the same\similar force as before being applied. The Sketch has been modified to accommodate this and with a multi-meter hooked up a range from 3.1v-1.9v is now seen.
Either increasing the Timer1 frequency from 490Hz to something considerably higher, or change the LPF component values.
GeekyDeaks ran some quick scope tests through the LPF, simulating the Pro Micro Board running at 8KHz,3.3v, with the default timer1 running at 245Hz (8000000/64/512) and then with an increased timer1 freq 15.6Khz (800000/1/512) for 1.9v output (brake fully on) - See Timer Info and Formulas below diagrams.
1.9v output 150 duty, input 3.3v for timer1 @ 245Hz
and
1.9v output 150 duty, input 3.42v for timer1 @ 15Khz
*Note the scopes results show there is a increase in voltage required to get the same 1.9v output at the higher frequency. Put another way, there would probably need to be some sketch code adjustment when running the timer1 at a higher frequency to get the desired PWM&LPF output values between 1.9v and 3.1v as duty cycles between 57.6% & 94.1% will be slightly out.
ATMega 32u4 data sheet specifies the following: 16-bit Timers/Counters (Timer/Counter1 and Timer/Counter3)
By default the init cmd sets the Timer1 Prescalar to div 64. This was determined by examining the hardware/arduino/avr/cores/arduino/wiring.c library code.
So timer1 default PWM freq (@16MHZ) = 16000000/64/512 = 489Hz.
512 = 2x256 (up and down counter for phase correct PWM)
Setting No prescalar (div 1): timer1 PWM @ f_CPU 16MHz = 32KHz (16000000/1/512) or at f_CPU 8MHz = 15.6KHz (8000000/1/512)
TCCR1B = (TCCR1B & 0b11111000) | 0b00000001;
The above code line MASKs off the 5 MSB's of TCCR1B , clears the lowest 3 LSB's (0b11111000) using the & (AND) and then sets the LSB#1 0b00000001 using |(or). With 0bxxxxx001 being div1: no prescalar. 0bxxxxx010 would set a div8 prescalar
Whilst trying to resolve the LPF issues with PWM running at a higher frequency the DAC board arrived.
Using this in place of the LPF has had a successful outcome after some slight re configuring of the Sketch code.
The DAC board is ran using the I2C protocol as a single Slave device. The DAC purchased, by default is set as single Slave device giving it and I2C address of 0x60.
DAC
Pin1 - OUT (Analogue Output)
Pin2 - GND
Pin3 - SCL
Pin4 - SDA
Pin5 - VCC
Pin6 - GND
Connecting up to the Pro Micro requires straight through connecting of SCL-SCL and SDA-SDA.
These are on the Pro Micro as Pin2 - SDA & Pin3 - SCL.
The Pro Micro requires library Wire.h for the I2C controls
#include <Wire.h>
The DACs address is setup with
#define MCP4725_ADDR 0x60
The pedal output code was changed from using PWM which was 256 intervals, to I2C with 4096 (12bit) for the DAC Intervals.
For Reference with 4.7v supply
3.1v - 2703
1.9v - 1638
or with a 3.3v supply:
3.1v - 3848
1.9v - 2358
3 Bytes are required to write the value that the DAC is to output as a voltage. A 3 byte Array is configured in the Sketch header.
byte buffer[3]
In the sketch loop section the 1st Byte (control byte) is configured so the DAC is in "write only" mode : 010
buffer[0] = 0xb01000000
The main loop code calculates the brake% voltage as before (using 4096 as the resolution rather than PWM's 256)
The DAC Value to be output is added to buffer[1] and buffer[2] as follows:
buffer[1] = dacValue >> 4 //Sets the most significant bit values
buffer[2] = dacValue << 4 //Sets the least significant bit values
The buffer array is then sent to the DAC with:
Wire.beginTransmission(MCP4725_ADDR);
Wire.write(buffer[0]); //Sends the control byte to I2C
Wire.write(buffer[1]); //Sends the MSB to IC2
Wire.write(buffer[2]); // Sends the LSB to IC2
Wire.endTransmission;
The MCP4725 can run at 100Kbps/KHz (by default) or 400Kbps/KHz.
Running at 100 seems to be OK in Gran Turismo Sport.
Sketch code has now been modified, after determining that the internal Pedal rod wasn't set right and the top nut was hitting the top of the 3D Printed cylinder, preventing the rod fully pushing down on the Load cell. By effectively making the rod longer, the load cell & HX711 now output values in the range of 1650000, which with the arbitrary scaling of 1100,the sketch code is now working up to a max value of -1500 rather the -120 that had previously been for the single cell setup and -750 for the original dual cell setup.
Code: 5v (running board off usb\for testing) use: SimPedal_dac_ver3.ino
NOTE: It would probably be easier to get a 3.3v Micro Pro, however these cost more than the 5v. I only have the 5v versions. If you used a 3.3v board, you'd just modify the 5v code (Code/SimPedal_ver3_dac.ino), changing the constant arduino_cc value from 4.7 to 3.3
Atmega32u4 Datasheet:
6.2.1Default Clock Source ATmega16U4 and ATmega32U4The device is shipped with Low Power Crystal Oscillator (8.0 - 16MHz) enabled and with the fuse CKDIV8 programmed, resulting in 1.0MHz system clock with an 8MHz crystal. See Table 28-5 on page 355 for an overview of the default Clock Selection Fuse setting.
This equates to the 32u4 lfuses, by default, being set to 0x5E.
The Arduino Pro Micro boards have their own 16MHz oscillator, so as far as the 32u4 is concerned it's oscillator is external.
Online fuse calculators detail 0xff to be "ext Oscillator, 8MHz , startup 16k +65ms" , from the datasheet...
lfuse 0xff:
CKSEL0:3 is 1111 - low power crystal oscillator. (SKSEL1:3 is 111 = freq range 8 - 16MHz)
SUT0:1 is 11 (with cksel0 1) - crystal oscillating, slow rising power
CKOUT is 1 - Clock Out/routed - off.
CKDIV8 is 1 - Divide clock by 8 off.
Create a new Menu Option in the Board.txt file (default location: C:\Program Files (x86)\Arduino\hardware\arduino\avr)
Code to Append is in Github repository code folder.
Fuses set as:
lfuse : changed from 0xff -> 0x7f (CKDiv8 set active - a Safe Bootloader Clock for running at 3.3v will now be 16/8 = 2MHz instead of 16Mhz)
hfuse : No change (0xd8)
xfuse : Changed from 0xcb -> 0xfe (Brown Out Detect - BOD - set to 2v from 2.6v)
unlock : No change (0x3f)
lock : No change (0x2f)
Also specify:
f_cpu = 8000000L
These menu settings should set the "bootloader" speeds for the lower 3.3 voltage @ 8Mhz and specify the "compiler/cpu speed"
The board, once booted, is still running at 16MHz (fuses only specify the bootload settings). So in the Sketch , set the board's freq to be 8Mhz with the following :
in the sketch header
#include <avr/power.h>
and putting in setup() :
//Div_2 - 16MHz /2 = 8Mhz
clock_prescale_set(clock_div_2);
Note: Changing the F_CPU from 16000000L will knock out the USB port (if one is still present!)
I used a 2nd Pro Micro (running at 5v with a USB port) to develop the sketch code and then use it as an ISP to upload the 3.3v Code to the Board that doesn't have a USB port.
Final project code for 5v Board running @ 3.3v Code/SimPedal_ver3_dac-3.3v.ino
https://playground.arduino.cc/Main/TimerPWMCheatsheet/
http://medesign.seas.upenn.edu/index.php/Guides/MaEvArM-timer1
Useful info: https://learn.sparkfun.com/tutorials/mcp4725-digital-to-analog-converter-hookup-guide/all
- 1x Arduino Pro Micro. Easiest solution is to use a 3.3v Version, but I've proved on here that the cheaper 5v version can be used (with some faff!)
- 1x HX711
- 1x MCP4725
- 2x 1K resistors
- 1x load cells
Pictured Below: "ISP" Arduino (left: Working USB) used to program broken USB Arduino (Right: USB fallen off)
https://embedds.com/all-you-need-to-know-about-avr-fuses/
http://www.martyncurrey.com/arduino-atmega-328p-fuse-settings/