Commit ae3d39de authored by Wouter Klop's avatar Wouter Klop

PCB updated to version 1.2: added RX pulldown resistor and 5V buffer capacitor...

PCB updated to version 1.2: added RX pulldown resistor and 5V buffer capacitor (both optional). Added some markings for buck converter.
Web interface now has a fancy option for logging data (plotTest.htm)
parent 5fb5ff6a
......@@ -2,8 +2,8 @@
This folder contains KiCad (5.0.0) design files for the BalancingRobot PCB.
# Features
* Supports both DRV8825 and A4988 based stepper drivers
* Supported voltage: 8 - 24V (2-6S LiPo/Li-ion)
* Supports both DRV8825 and A4988 based stepper drivers. Should also be compatible with TMC2100 (with settings configurable via ESP32), not tested yet though.
* Supported voltage: ~7 - 24V (2-6S LiPo/Li-ion)
* Digital current control of steppers (you'll need to desolder the potmeter and add a wire)
* Dynamic microstep switching, allowing for insane speeds
* Connections:
......@@ -51,7 +51,8 @@ For better performance, you can tie the decay mode pin of the DRV8825 to VCC, se
## Auxiliary header
Connector J2 has a grid of 12 pins (3x4), with some general pins broken out, together with all unused ESP32 IO pins. See the close-up of the header below. Pin numbering in this picture is used in the table below to identify pins.
![Auxiliary header pinout](/PCB/pictures/auxHeader.PNG)
//![Auxiliary header pinout](/PCB/pictures/auxHeader.PNG)
<img src="/PCB/pictures/auxHeader.PNG" width="400" />
| Pin # | Name | ESP32 pin |
|-------|---------|-----------|
......@@ -108,10 +109,9 @@ Initial version
* Added second via in 24V trace, or rather added trace to second via which wasn't there in v1.0
* Swapped + and - symbols on silkscreen close to RX header
* Added a 10k pull-up on the stepper driver enable. In v1.0, no pull-up is present, meaning the steppers are enabled if the ESP32 isn't running. No big deal, but somewhat neater to disable steppers if the ESP32 isn't running.
## v1.2
* Added optional 100k RX pulldown resistor
* Added optional 5V filtering cap (might be useful if for example some Neopixels are connected to 5V line)
* Added some markings for the buck converter, clarifying the mounting direction
* Added connections for (fused) battery voltage (J6)
# To do for this readme
* Add picture of assembled board
* Add some pictures to the assembly section
* Add J2 header pinout
* Stepper current adjustment
* Refer to next steps
......@@ -723,8 +723,6 @@ Wire Wire Line
1950 4200 1450 4200
Text Label 1450 4200 0 50 ~ 0
SERVO_PWM
Wire Wire Line
1950 3800 1450 3800
Text Label 1450 3800 0 50 ~ 0
IBUS_RX
Wire Wire Line
......@@ -1108,7 +1106,7 @@ L Device:R R7
U 1 1 5BE75466
P 4950 4100
F 0 "R7" H 5020 4146 50 0000 L CNN
F 1 "10k" H 5020 4055 50 0000 L CNN
F 1 "3k3" H 5020 4055 50 0000 L CNN
F 2 "Resistors_SMD:R_0805_HandSoldering" V 4880 4100 50 0001 C CNN
F 3 "~" H 4950 4100 50 0001 C CNN
1 4950 4100
......@@ -1123,4 +1121,57 @@ Wire Wire Line
Wire Wire Line
4950 3900 5300 3900
Connection ~ 4950 3900
$Comp
L Device:R R8
U 1 1 5C596ABB
P 1150 4050
F 0 "R8" H 1220 4096 50 0000 L CNN
F 1 "100k" H 1220 4005 50 0000 L CNN
F 2 "Resistors_SMD:R_0805_HandSoldering" V 1080 4050 50 0001 C CNN
F 3 "~" H 1150 4050 50 0001 C CNN
1 1150 4050
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR02
U 1 1 5C596B33
P 1150 4250
F 0 "#PWR02" H 1150 4000 50 0001 C CNN
F 1 "GND" H 1155 4077 50 0000 C CNN
F 2 "" H 1150 4250 50 0001 C CNN
F 3 "" H 1150 4250 50 0001 C CNN
1 1150 4250
1 0 0 -1
$EndComp
Wire Wire Line
1150 4250 1150 4200
Wire Wire Line
1150 3900 1150 3800
Wire Wire Line
1150 3800 1950 3800
$Comp
L Device:CP C6
U 1 1 5C5A6BE2
P 6150 2150
F 0 "C6" H 6268 2196 50 0000 L CNN
F 1 "470u" H 6268 2105 50 0000 L CNN
F 2 "Capacitors_THT:CP_Radial_D6.3mm_P2.50mm" H 6188 2000 50 0001 C CNN
F 3 "~" H 6150 2150 50 0001 C CNN
1 6150 2150
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR03
U 1 1 5C5A6C84
P 6150 2300
F 0 "#PWR03" H 6150 2050 50 0001 C CNN
F 1 "GND" H 6155 2127 50 0000 C CNN
F 2 "" H 6150 2300 50 0001 C CNN
F 3 "" H 6150 2300 50 0001 C CNN
1 6150 2300
1 0 0 -1
$EndComp
Wire Wire Line
6150 2000 6150 1950
Connection ~ 6150 1950
$EndSCHEMATC
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
......@@ -723,8 +723,6 @@ Wire Wire Line
1950 4200 1450 4200
Text Label 1450 4200 0 50 ~ 0
SERVO_PWM
Wire Wire Line
1950 3800 1450 3800
Text Label 1450 3800 0 50 ~ 0
IBUS_RX
Wire Wire Line
......@@ -1123,4 +1121,98 @@ Wire Wire Line
Wire Wire Line
4950 3900 5300 3900
Connection ~ 4950 3900
$Comp
L Device:R R8
U 1 1 5C596ABB
P 1150 4050
F 0 "R8" H 1220 4096 50 0000 L CNN
F 1 "100k" H 1220 4005 50 0000 L CNN
F 2 "Resistors_SMD:R_0805_HandSoldering" V 1080 4050 50 0001 C CNN
F 3 "~" H 1150 4050 50 0001 C CNN
1 1150 4050
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR02
U 1 1 5C596B33
P 1150 4250
F 0 "#PWR02" H 1150 4000 50 0001 C CNN
F 1 "GND" H 1155 4077 50 0000 C CNN
F 2 "" H 1150 4250 50 0001 C CNN
F 3 "" H 1150 4250 50 0001 C CNN
1 1150 4250
1 0 0 -1
$EndComp
Wire Wire Line
1150 4250 1150 4200
Wire Wire Line
1150 3900 1150 3800
Wire Wire Line
1150 3800 1950 3800
$Comp
L Device:CP C6
U 1 1 5C5A6BE2
P 6150 2150
F 0 "C6" H 6268 2196 50 0000 L CNN
F 1 "470u" H 6268 2105 50 0000 L CNN
F 2 "Capacitors_THT:CP_Radial_D6.3mm_P2.50mm" H 6188 2000 50 0001 C CNN
F 3 "~" H 6150 2150 50 0001 C CNN
1 6150 2150
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR03
U 1 1 5C5A6C84
P 6150 2300
F 0 "#PWR03" H 6150 2050 50 0001 C CNN
F 1 "GND" H 6155 2127 50 0000 C CNN
F 2 "" H 6150 2300 50 0001 C CNN
F 3 "" H 6150 2300 50 0001 C CNN
1 6150 2300
1 0 0 -1
$EndComp
Wire Wire Line
6150 2000 6150 1950
Connection ~ 6150 1950
$Comp
L Connector:Conn_01x02_Male J6
U 1 1 5C5AF1E1
P 2500 2650
F 0 "J6" H 2606 2828 50 0000 C CNN
F 1 "Conn_01x02_Male" H 2606 2737 50 0000 C CNN
F 2 "mylib:pinHeader_2x1_5.08mm" H 2500 2650 50 0001 C CNN
F 3 "~" H 2500 2650 50 0001 C CNN
1 2500 2650
1 0 0 -1
$EndComp
$Comp
L power:+24V #PWR04
U 1 1 5C5AF287
P 3050 2600
F 0 "#PWR04" H 3050 2450 50 0001 C CNN
F 1 "+24V" H 3065 2773 50 0000 C CNN
F 2 "" H 3050 2600 50 0001 C CNN
F 3 "" H 3050 2600 50 0001 C CNN
1 3050 2600
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR05
U 1 1 5C5AF2CA
P 3050 2800
F 0 "#PWR05" H 3050 2550 50 0001 C CNN
F 1 "GND" H 3055 2627 50 0000 C CNN
F 2 "" H 3050 2800 50 0001 C CNN
F 3 "" H 3050 2800 50 0001 C CNN
1 3050 2800
1 0 0 -1
$EndComp
Wire Wire Line
2700 2750 3050 2750
Wire Wire Line
3050 2750 3050 2800
Wire Wire Line
3050 2650 3050 2600
Wire Wire Line
2700 2650 3050 2650
$EndSCHEMATC
......@@ -5,10 +5,14 @@
</head>
<body>
<canvas id="chartContainer" height=300"px" width=800p" style="border:1px solid #d3d3d3;"></canvas><br />
<canvas id="chartContainer" height="300px" width="800px" style="border:1px solid #d3d3d3;"></canvas><br />
<button name="plotStart" onclick="plotStartStop(1)" style="width:80px">Start</button>
<button name="plotSTop" onclick="plotStartStop(0)" style="width:80px">Stop</button><br /><br />
<button name="plotStop" onclick="plotStartStop(0)" style="width:80px">Stop</button>
<button name="plotClear" style="width:80px">Clear</button><br /><br />
<fieldset style="width:300px">
<legend>Plot control</legend>
Sample rate [Hz]:<br />
<input id="plotRate" type="radio" name="sampleRate" value="8">25
<input id="plotRate" type="radio" name="sampleRate" value="4" checked>50
......@@ -29,6 +33,23 @@ Signals to plot<br />
<input type="checkbox" name="plotOption" id="PID3output" onchange=plotOption(this);>PID speed output<br />
<input type="checkbox" name="plotOption" id="motLeftSpeed" onchange=plotOption(this);>Left motor speed<br />
<input type="checkbox" name="plotOption" id="motRightSpeed" onchange=plotOption(this);>Right motor speed<br />
</fieldset>
<fieldset style="width:300px">
<legend>Logging</legend>
<input type="checkbox" id="logEnable">Enable logging<br /><br />
Time elapsed [s]: <label id="logDuration">0</label><br /><br />
<button id="logClear" onclick="clearLogData()">Clear</button>
<button id="logExport" onclick="exportLogData()">Export</button>
</fieldset>
<fieldset style="width:300px">
<legend>Signal generation</legend>
Amplitude
On / off
Location
</fieldset>
</body>
<script>
......@@ -38,10 +59,12 @@ var ctx = canvas.getContext('2d');
var nSample = 500;
var nSignal = 11;
var nSignal = 12;
var yLim = [-100, 100];
var col = ["blue","red","green"];
var sampleRate = 0;
var plotEnabled = new Array();
// Init data array
......@@ -49,11 +72,14 @@ var data = new Array(nSignal);
for (var i=0; i<nSignal; i++) data[i] = new Array(nSample);
for (var i=0; i<nSignal; i++) data[i].fill(0,0,nSample);
var logData = new Array(nSignal);
for (var i=0; i<nSignal; i++) logData[i] = new Array;
var updateChart = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i=0; i<plotEnabled.length; i++) {
var signalNo = plotEnabled[i];
<!--for (var i=0; i<nSignal; i++) {-->
var signalNo = plotEnabled[i] + 1;
ctx.beginPath();
for (var j=0; j<nSample; j++) {
var x = j * canvas.clientWidth/nSample;
......@@ -70,42 +96,83 @@ var updateChart = function() {
}
}
var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);
connection.binaryType = 'arraybuffer';
connection.onopen = function () {
};
connection.onerror = function (error) {
console.log('WebSocket Error ', error);
};
connection.onmessage = function (e) {
if (typeof(e.data)=='string') { // Text frame
} else { // Binary
var d = e.data;
var dv = new DataView(d);
cmd = dv.getUint8(0);
if (cmd==255) {
for (var i=0; i<nSignal; i++) {
var val = dv.getFloat32(4+i*4, true);
data[i].push(val);
data[i].shift();
if (document.getElementById('logEnable').checked) {
logData[i].push(val);
document.getElementById('logDuration').innerHTML = Number(logData[0].length/sampleRate).toFixed(2);
}
}
updateChart();
}
}
};
var exportLogData = function() {
var l = logData[0].length;
if (l>0) {
var csvFile = '';
for (var i=0; i<l; i++) {
for (var j=0; j<nSignal; j++) {
// logData.forEach(function(x) {
// console.log(x.length)
var x = logData[j];
var val = x[i];
// csvFile += val.toString() + ',';
csvFile += Number(logData[j][i]).toFixed(6);
if (j<nSignal-1) csvFile += ',';
}
csvFile += '\n';
}
// console.log(logData[0][0].toFixed(5))
var filename = 'logData.csv';
var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, filename);
} else {
var link = document.createElement("a");
if (link.download !== undefined) { // feature detection
// Browsers that support HTML5 download attribute
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
}
console.time('updateChart');
updateChart();
console.timeEnd('updateChart');
var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);
connection.binaryType = 'arraybuffer';
connection.onopen = function () {
<!-- connection.send('Connect ' + new Date()); -->
};
connection.onerror = function (error) {
console.log('WebSocket Error ', error);
};
connection.onmessage = function (e) {
if (typeof(e.data)=='string') { // Text frame
} else { // Binary
var d = e.data;
var dv = new DataView(d);
var text = '';
for (var i=0; i<dv.byteLength; i++) {
text += dv.getUint8(i) + ' ';
}
cmd = dv.getUint8(0);
t = dv.getUint32(4,true)/1000000;
for (var i=0; i<nSignal; i++) {
var val = dv.getFloat32(8+i*4, true);
data[i].push(val);
data[i].shift();
}
updateChart();
<!--console.log(val);-->
<!--console.log(text);-->
// console.log(dv.getFloat32(0),false);
}
};
var clearLogData = function() {
for (var i=0; i<nSignal; i++) logData[i] = [];
document.getElementById('logDuration').innerHTML = '0';
}
var plotStartStop = function (x) {
var radioButtons = document.getElementsByName("sampleRate");
......@@ -114,10 +181,30 @@ var plotStartStop = function (x) {
if (radioButtons[i].checked) break;
prescaler /= 2;
}
sendCommand('h', x);
sendCommand('i', prescaler);
// Toggle user input disable/enable
var b = x==1;
e = document.getElementsByName("sampleRate");
for (var i=0; i<e.length; i++) {
e[i].disabled = b;
}
document.getElementById("logEnable").disabled = b;
document.getElementById("logClear").disabled = b;
document.getElementById("logExport").disabled = b;
sampleRate = 200/prescaler;
plotOption();
// If logging enabled, init array for data.
}
// Find which signals are to be plotted
var plotOption = function(e) {
var plotOptions = document.getElementsByName("plotOption");
var plotOptionLength = plotOptions.length;
......@@ -127,12 +214,8 @@ var plotOption = function(e) {
for (var i=0; i<plotOptionLength; i++) {
if (plotOptions[i].checked) {
plotEnabled[plotCount++] = i;
}
}
}
<!--console.log(plotEnabled.length);-->
<!--for (var i=0; i<plotEnabled.length; i++) {-->
<!--console.log(plotEnabled[i]);-->
<!--}-->
}
function sendCommand(cmd, val) {
......
......@@ -500,24 +500,23 @@ void loop() {
uint8_t fill1;
uint8_t fill2;
uint8_t fill3;
uint32_t time;
float f[11];
float f[12];
};
uint8_t b[52];
} plotData;
plotData.time = micros();
plotData.f[0] = accAngle;
plotData.f[1] = filterAngle;
plotData.f[2] = pidAngle.setpoint;
plotData.f[3] = pidAngle.input;
plotData.f[4] = pidAngleOutput;
plotData.f[5] = pidPos.setpoint;
plotData.f[6] = pidPos.input;
plotData.f[7] = pidPosOutput;
plotData.f[8] = pidSpeed.setpoint;
plotData.f[9] = pidSpeed.input;
plotData.f[10] = pidSpeedOutput;
plotData.f[0] = micros()/1000000.0;
plotData.f[1] = accAngle;
plotData.f[2] = filterAngle;
plotData.f[3] = pidAngle.setpoint;
plotData.f[4] = pidAngle.input;
plotData.f[5] = pidAngleOutput;
plotData.f[6] = pidPos.setpoint;
plotData.f[7] = pidPos.input;
plotData.f[8] = pidPosOutput;
plotData.f[9] = pidSpeed.setpoint;
plotData.f[10] = pidSpeed.input;
plotData.f[11] = pidSpeedOutput;
wsServer.sendBIN(0, plotData.b, sizeof(plotData.b));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment