Initial commit

This commit is contained in:
2025-01-09 18:23:19 +01:00
commit 3a636067f4
51 changed files with 356370 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
UnitFirmware/module_rev0/build/*
UnitFirmware/module_rev0/build
Server/build/*
Server/build
ModuleController/ModuleController-backups/*
ModuleController/ModuleController-backups

59
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,59 @@
{
"env": {
"myIncludePath": ["${workspaceFolder}/include", "${workspaceFolder}/src"],
"myDefines": ["DEBUG", "MY_FEATURE=1"]
},
"configurations": [
{
"name": "Linux",
"compilerPath": "/usr/bin/avr-gcc",
"compilerArgs": ["-mmcu=atmega8", "-DF_CPU=16000000UL", "-Os"],
"intelliSenseMode": "linux-gcc-x86",
"includePath": ["${myIncludePath}", "/usr/include"],
"defines": ["${myDefines}"],
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"configurationProvider": "ms-vscode.cmake-tools",
"forcedInclude": ["${workspaceFolder}/common.h"],
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"dotConfig": "${workspaceFolder}/.config",
"mergeConfigurations": true,
"customConfigurationVariables": {
"myVar": "myvalue"
},
"browse": {
"path": ["${myIncludePath}", "/usr/include", "${workspaceFolder}"],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": "${workspaceFolder}/.vscode/browse.vc.db"
}
},
{
"name": "Mac",
"compilerPath": "/usr/bin/clang",
"intelliSenseMode": "macos-clang-x64",
"includePath": ["${myIncludePath}"],
"defines": ["${myDefines}"],
"cStandard": "c11",
"cppStandard": "c++17",
"macFrameworkPath": ["/System/Library/Frameworks", "/Library/Frameworks"],
"browse": {
"path": ["${myIncludePath}", "${workspaceFolder}"]
}
},
{
"name": "Win32",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe",
"intelliSenseMode": "windows-msvc-x64",
"includePath": ["${myIncludePath}"],
"defines": ["${myDefines}", "_WINDOWS"],
"cStandard": "c17",
"cppStandard": "c++20",
"windowsSdkVersion": "10.0.19041.0",
"browse": {
"path": ["${myIncludePath}", "${workspaceFolder}"]
}
}
],
"version": 4,
"enableConfigurationSquiggles": true
}

BIN
ModuleController/GBR/GBR.zip Executable file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,129 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:46+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Bot*%
%TF.FilePolarity,Negative*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:46*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10C,0.100000*%
%ADD11C,2.000000*%
%ADD12C,3.200000*%
%ADD13RoundRect,0.900000X3.384000X-1.132000X3.384000X1.132000X-3.384000X1.132000X-3.384000X-1.132000X0*%
%ADD14O,8.500000X1.524000*%
%ADD15O,1.950000X1.700000*%
%ADD16RoundRect,0.250000X-0.725000X0.600000X-0.725000X-0.600000X0.725000X-0.600000X0.725000X0.600000X0*%
%ADD17C,1.600000*%
%ADD18R,1.600000X1.600000*%
%ADD19C,1.500000*%
%ADD20O,1.600000X1.600000*%
G04 APERTURE END LIST*
D10*
%TO.C,J6*%
X145857000Y-121920000D02*
X154747000Y-121920000D01*
X154747000Y-121920000D02*
X154747000Y-99060000D01*
X154747000Y-99060000D02*
X145857000Y-99060000D01*
X145857000Y-99060000D02*
X145857000Y-121920000D01*
G36*
X145857000Y-121920000D02*
G01*
X154747000Y-121920000D01*
X154747000Y-99060000D01*
X145857000Y-99060000D01*
X145857000Y-121920000D01*
G37*
%TD*%
D11*
%TO.C,F1*%
X143510000Y-91868000D03*
X143510000Y-86868000D03*
%TD*%
D12*
%TO.C,H3*%
X122555000Y-40640000D03*
%TD*%
%TO.C,H2*%
X90170000Y-122555000D03*
%TD*%
%TO.C,H1*%
X121285000Y-122555000D03*
%TD*%
D13*
%TO.C,J6*%
X150209000Y-102870000D03*
D14*
X150175000Y-106680000D03*
X150175000Y-109220000D03*
X150175000Y-111760000D03*
X150175000Y-114300000D03*
X150175000Y-116840000D03*
X150175000Y-119380000D03*
D13*
X150209000Y-102870000D03*
%TD*%
D15*
%TO.C,J1*%
X140208000Y-58768000D03*
X140208000Y-56268000D03*
X140208000Y-53768000D03*
X140208000Y-51268000D03*
D16*
X140208000Y-48768000D03*
%TD*%
D17*
%TO.C,C2*%
X142748000Y-96560000D03*
D18*
X142748000Y-99060000D03*
%TD*%
D19*
%TO.C,Y1*%
X124604000Y-114300000D03*
X119724000Y-114300000D03*
%TD*%
D17*
%TO.C,C1*%
X139954000Y-67524000D03*
D18*
X139954000Y-65024000D03*
%TD*%
D20*
%TO.C,U3*%
X143266000Y-116596000D03*
X143266000Y-119136000D03*
X143266000Y-121676000D03*
X143266000Y-124216000D03*
X135646000Y-124216000D03*
X135646000Y-121676000D03*
X135646000Y-119136000D03*
D18*
X135646000Y-116596000D03*
%TD*%
M02*

View File

@@ -0,0 +1,15 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:46+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Paste,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:46*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@@ -0,0 +1,15 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:46+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Legend,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:46*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@@ -0,0 +1,60 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:46+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Profile,NP*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:46*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%TA.AperFunction,Profile*%
%ADD10C,0.100000*%
%TD*%
%TA.AperFunction,Profile*%
%ADD11C,0.050000*%
%TD*%
G04 APERTURE END LIST*
D10*
X86360000Y-65405000D02*
X101600000Y-36830000D01*
X143190000Y-47625000D02*
X146365000Y-47625000D01*
X143190000Y-60325000D02*
X143190000Y-47625000D01*
X146360000Y-60325000D02*
X143190000Y-60325000D01*
X146360000Y-36830000D02*
X146365000Y-47625000D01*
X146360000Y-126830000D02*
X146365000Y-121920000D01*
X146365000Y-99060000D02*
X146360000Y-60325000D01*
X86360000Y-126830000D02*
X146360000Y-126830000D01*
X101600000Y-36830000D02*
X146360000Y-36830000D01*
X86360000Y-126830000D02*
X86360000Y-65405000D01*
D11*
%TO.C,J6*%
X154620000Y-99695000D02*
G75*
G03*
X153985000Y-99060000I-635000J0D01*
G01*
X153985000Y-121920000D02*
G75*
G03*
X154620000Y-121285000I1J634999D01*
G01*
X153985000Y-99060000D02*
X146365000Y-99060000D01*
X154620000Y-121285000D02*
X154620000Y-99695000D01*
X146365000Y-121920000D02*
X153985000Y-121920000D01*
%TD*%
M02*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,240 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:46+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Top*%
%TF.FilePolarity,Negative*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:46*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10C,0.100000*%
%ADD11RoundRect,0.250000X-0.262500X-0.450000X0.262500X-0.450000X0.262500X0.450000X-0.262500X0.450000X0*%
%ADD12C,2.000000*%
%ADD13RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD14RoundRect,0.250000X0.262500X0.450000X-0.262500X0.450000X-0.262500X-0.450000X0.262500X-0.450000X0*%
%ADD15R,1.600000X0.550000*%
%ADD16R,0.550000X1.600000*%
%ADD17R,1.000000X0.700000*%
%ADD18RoundRect,0.250000X-0.475000X0.250000X-0.475000X-0.250000X0.475000X-0.250000X0.475000X0.250000X0*%
%ADD19C,3.200000*%
%ADD20O,8.500000X1.524000*%
%ADD21O,1.950000X1.700000*%
%ADD22RoundRect,0.250000X-0.725000X0.600000X-0.725000X-0.600000X0.725000X-0.600000X0.725000X0.600000X0*%
%ADD23C,1.600000*%
%ADD24R,1.600000X1.600000*%
%ADD25RoundRect,0.250000X0.250000X0.475000X-0.250000X0.475000X-0.250000X-0.475000X0.250000X-0.475000X0*%
%ADD26C,1.500000*%
%ADD27R,0.600000X1.500000*%
%ADD28O,1.600000X1.600000*%
G04 APERTURE END LIST*
D10*
%TO.C,J6*%
X145857000Y-121920000D02*
X154747000Y-121920000D01*
X154747000Y-121920000D02*
X154747000Y-99060000D01*
X154747000Y-99060000D02*
X145857000Y-99060000D01*
X145857000Y-99060000D02*
X145857000Y-121920000D01*
G36*
X145857000Y-121920000D02*
G01*
X154747000Y-121920000D01*
X154747000Y-99060000D01*
X145857000Y-99060000D01*
X145857000Y-121920000D01*
G37*
%TD*%
D11*
%TO.C,R3*%
X138637000Y-91694000D03*
X140462000Y-91694000D03*
%TD*%
%TO.C,R2*%
X138637000Y-88744000D03*
X140462000Y-88744000D03*
%TD*%
D12*
%TO.C,F1*%
X143510000Y-91868000D03*
X143510000Y-86868000D03*
%TD*%
D13*
%TO.C,C6*%
X117480000Y-107188000D03*
X119380000Y-107188000D03*
%TD*%
D14*
%TO.C,R1*%
X133397000Y-121666000D03*
X131572000Y-121666000D03*
%TD*%
D15*
%TO.C,U4*%
X121588000Y-103186000D03*
X121588000Y-103986000D03*
X121588000Y-104786000D03*
X121588000Y-105586000D03*
X121588000Y-106386000D03*
X121588000Y-107186000D03*
X121588000Y-107986000D03*
X121588000Y-108786000D03*
D16*
X123038000Y-110236000D03*
X123838000Y-110236000D03*
X124638000Y-110236000D03*
X125438000Y-110236000D03*
X126238000Y-110236000D03*
X127038000Y-110236000D03*
X127838000Y-110236000D03*
X128638000Y-110236000D03*
D15*
X130088000Y-108786000D03*
X130088000Y-107986000D03*
X130088000Y-107186000D03*
X130088000Y-106386000D03*
X130088000Y-105586000D03*
X130088000Y-104786000D03*
X130088000Y-103986000D03*
X130088000Y-103186000D03*
D16*
X128638000Y-101736000D03*
X127838000Y-101736000D03*
X127038000Y-101736000D03*
X126238000Y-101736000D03*
X125438000Y-101736000D03*
X124638000Y-101736000D03*
X123838000Y-101736000D03*
X123038000Y-101736000D03*
%TD*%
D17*
%TO.C,U2*%
X93800000Y-70860000D03*
X93800000Y-72760000D03*
X96200000Y-71810000D03*
%TD*%
D12*
%TO.C,TP9*%
X111252000Y-122428000D03*
%TD*%
%TO.C,TP8*%
X107202000Y-122428000D03*
%TD*%
%TO.C,TP7*%
X103152000Y-122428000D03*
%TD*%
D18*
%TO.C,C5*%
X132842000Y-105730000D03*
X132842000Y-107630000D03*
%TD*%
D19*
%TO.C,H3*%
X122555000Y-40640000D03*
%TD*%
%TO.C,H2*%
X90170000Y-122555000D03*
%TD*%
%TO.C,H1*%
X121285000Y-122555000D03*
%TD*%
D20*
%TO.C,J6*%
X150175000Y-106680000D03*
X150175000Y-109220000D03*
X150175000Y-111760000D03*
X150175000Y-114300000D03*
X150175000Y-116840000D03*
X150175000Y-119380000D03*
%TD*%
D21*
%TO.C,J1*%
X140208000Y-58768000D03*
X140208000Y-56268000D03*
X140208000Y-53768000D03*
X140208000Y-51268000D03*
D22*
X140208000Y-48768000D03*
%TD*%
D23*
%TO.C,C2*%
X142748000Y-96560000D03*
D24*
X142748000Y-99060000D03*
%TD*%
D25*
%TO.C,C3*%
X129098000Y-116332000D03*
X130998000Y-116332000D03*
%TD*%
D26*
%TO.C,Y1*%
X124604000Y-114300000D03*
X119724000Y-114300000D03*
%TD*%
D23*
%TO.C,C1*%
X139954000Y-67524000D03*
D24*
X139954000Y-65024000D03*
%TD*%
D25*
%TO.C,C4*%
X129098000Y-114046000D03*
X130998000Y-114046000D03*
%TD*%
D27*
%TO.C,U1*%
X125603000Y-57664000D03*
X126873000Y-57664000D03*
X128143000Y-57664000D03*
X129413000Y-57664000D03*
X130683000Y-57664000D03*
X131953000Y-57664000D03*
X133223000Y-57664000D03*
X134493000Y-57664000D03*
X134493000Y-64764000D03*
X133223000Y-64764000D03*
X131953000Y-64764000D03*
X130683000Y-64764000D03*
X129413000Y-64764000D03*
X128143000Y-64764000D03*
X126873000Y-64764000D03*
X125603000Y-64764000D03*
%TD*%
D28*
%TO.C,U3*%
X143266000Y-116596000D03*
X143266000Y-119136000D03*
X143266000Y-121676000D03*
X143266000Y-124216000D03*
X135646000Y-124216000D03*
X135646000Y-121676000D03*
X135646000Y-119136000D03*
D24*
X135646000Y-116596000D03*
%TD*%
M02*

View File

@@ -0,0 +1,138 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:46+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Paste,Top*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:46*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.250000X-0.262500X-0.450000X0.262500X-0.450000X0.262500X0.450000X-0.262500X0.450000X0*%
%ADD11RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD12RoundRect,0.250000X0.262500X0.450000X-0.262500X0.450000X-0.262500X-0.450000X0.262500X-0.450000X0*%
%ADD13R,1.600000X0.550000*%
%ADD14R,0.550000X1.600000*%
%ADD15R,1.000000X0.700000*%
%ADD16RoundRect,0.250000X-0.475000X0.250000X-0.475000X-0.250000X0.475000X-0.250000X0.475000X0.250000X0*%
%ADD17RoundRect,0.250000X0.250000X0.475000X-0.250000X0.475000X-0.250000X-0.475000X0.250000X-0.475000X0*%
%ADD18R,0.600000X1.500000*%
G04 APERTURE END LIST*
D10*
%TO.C,R3*%
X138637000Y-91694000D03*
X140462000Y-91694000D03*
%TD*%
%TO.C,R2*%
X138637000Y-88744000D03*
X140462000Y-88744000D03*
%TD*%
D11*
%TO.C,C6*%
X117480000Y-107188000D03*
X119380000Y-107188000D03*
%TD*%
D12*
%TO.C,R1*%
X133397000Y-121666000D03*
X131572000Y-121666000D03*
%TD*%
D13*
%TO.C,U4*%
X121588000Y-103186000D03*
X121588000Y-103986000D03*
X121588000Y-104786000D03*
X121588000Y-105586000D03*
X121588000Y-106386000D03*
X121588000Y-107186000D03*
X121588000Y-107986000D03*
X121588000Y-108786000D03*
D14*
X123038000Y-110236000D03*
X123838000Y-110236000D03*
X124638000Y-110236000D03*
X125438000Y-110236000D03*
X126238000Y-110236000D03*
X127038000Y-110236000D03*
X127838000Y-110236000D03*
X128638000Y-110236000D03*
D13*
X130088000Y-108786000D03*
X130088000Y-107986000D03*
X130088000Y-107186000D03*
X130088000Y-106386000D03*
X130088000Y-105586000D03*
X130088000Y-104786000D03*
X130088000Y-103986000D03*
X130088000Y-103186000D03*
D14*
X128638000Y-101736000D03*
X127838000Y-101736000D03*
X127038000Y-101736000D03*
X126238000Y-101736000D03*
X125438000Y-101736000D03*
X124638000Y-101736000D03*
X123838000Y-101736000D03*
X123038000Y-101736000D03*
%TD*%
D15*
%TO.C,U2*%
X93800000Y-70860000D03*
X93800000Y-72760000D03*
X96200000Y-71810000D03*
%TD*%
D16*
%TO.C,C5*%
X132842000Y-105730000D03*
X132842000Y-107630000D03*
%TD*%
D17*
%TO.C,C3*%
X129098000Y-116332000D03*
X130998000Y-116332000D03*
%TD*%
%TO.C,C4*%
X129098000Y-114046000D03*
X130998000Y-114046000D03*
%TD*%
D18*
%TO.C,U1*%
X125603000Y-57664000D03*
X126873000Y-57664000D03*
X128143000Y-57664000D03*
X129413000Y-57664000D03*
X130683000Y-57664000D03*
X131953000Y-57664000D03*
X133223000Y-57664000D03*
X134493000Y-57664000D03*
X134493000Y-64764000D03*
X133223000Y-64764000D03*
X131953000Y-64764000D03*
X130683000Y-64764000D03*
X129413000Y-64764000D03*
X128143000Y-64764000D03*
X126873000Y-64764000D03*
X125603000Y-64764000D03*
%TD*%
M02*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,944 @@
%TF.GenerationSoftware,KiCad,Pcbnew,7.0.5*%
%TF.CreationDate,2024-09-11T17:05:49+02:00*%
%TF.ProjectId,ModuleController,4d6f6475-6c65-4436-9f6e-74726f6c6c65,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Drillmap*%
%TF.FilePolarity,Positive*%
%FSLAX45Y45*%
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.5) date 2024-09-11 17:05:49*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.100000*%
%ADD11C,0.200000*%
%ADD12C,0.320000*%
G04 APERTURE END LIST*
D10*
X8636000Y-6540500D02*
X10160000Y-3683000D01*
X14319000Y-4762500D02*
X14636500Y-4762500D01*
X14319000Y-6032500D02*
X14319000Y-4762500D01*
X14636000Y-6032500D02*
X14319000Y-6032500D01*
X14636000Y-3683000D02*
X14636500Y-4762500D01*
X14636000Y-12683000D02*
X14636500Y-12192000D01*
X14636500Y-9906000D02*
X14636000Y-6032500D01*
X8636000Y-12683000D02*
X14636000Y-12683000D01*
X10160000Y-3683000D02*
X14636000Y-3683000D01*
X8636000Y-12683000D02*
X8636000Y-6540500D01*
D11*
D12*
X8857000Y-12095500D02*
X9177000Y-12415500D01*
X9177000Y-12095500D02*
X8857000Y-12415500D01*
X11968500Y-12095500D02*
X12288500Y-12415500D01*
X12288500Y-12095500D02*
X11968500Y-12415500D01*
X12095500Y-3904000D02*
X12415500Y-4224000D01*
X12415500Y-3904000D02*
X12095500Y-4224000D01*
D11*
X8891777Y-12999484D02*
X8891777Y-12799484D01*
X8891777Y-12799484D02*
X8939396Y-12799484D01*
X8939396Y-12799484D02*
X8967967Y-12809008D01*
X8967967Y-12809008D02*
X8987015Y-12828055D01*
X8987015Y-12828055D02*
X8996539Y-12847103D01*
X8996539Y-12847103D02*
X9006063Y-12885198D01*
X9006063Y-12885198D02*
X9006063Y-12913769D01*
X9006063Y-12913769D02*
X8996539Y-12951865D01*
X8996539Y-12951865D02*
X8987015Y-12970912D01*
X8987015Y-12970912D02*
X8967967Y-12989960D01*
X8967967Y-12989960D02*
X8939396Y-12999484D01*
X8939396Y-12999484D02*
X8891777Y-12999484D01*
X9091777Y-12999484D02*
X9091777Y-12866150D01*
X9091777Y-12904246D02*
X9101301Y-12885198D01*
X9101301Y-12885198D02*
X9110824Y-12875674D01*
X9110824Y-12875674D02*
X9129872Y-12866150D01*
X9129872Y-12866150D02*
X9148920Y-12866150D01*
X9215586Y-12999484D02*
X9215586Y-12866150D01*
X9215586Y-12799484D02*
X9206063Y-12809008D01*
X9206063Y-12809008D02*
X9215586Y-12818531D01*
X9215586Y-12818531D02*
X9225110Y-12809008D01*
X9225110Y-12809008D02*
X9215586Y-12799484D01*
X9215586Y-12799484D02*
X9215586Y-12818531D01*
X9339396Y-12999484D02*
X9320348Y-12989960D01*
X9320348Y-12989960D02*
X9310824Y-12970912D01*
X9310824Y-12970912D02*
X9310824Y-12799484D01*
X9444158Y-12999484D02*
X9425110Y-12989960D01*
X9425110Y-12989960D02*
X9415586Y-12970912D01*
X9415586Y-12970912D02*
X9415586Y-12799484D01*
X9672729Y-12999484D02*
X9672729Y-12799484D01*
X9672729Y-12799484D02*
X9739396Y-12942341D01*
X9739396Y-12942341D02*
X9806063Y-12799484D01*
X9806063Y-12799484D02*
X9806063Y-12999484D01*
X9987015Y-12999484D02*
X9987015Y-12894722D01*
X9987015Y-12894722D02*
X9977491Y-12875674D01*
X9977491Y-12875674D02*
X9958444Y-12866150D01*
X9958444Y-12866150D02*
X9920348Y-12866150D01*
X9920348Y-12866150D02*
X9901301Y-12875674D01*
X9987015Y-12989960D02*
X9967967Y-12999484D01*
X9967967Y-12999484D02*
X9920348Y-12999484D01*
X9920348Y-12999484D02*
X9901301Y-12989960D01*
X9901301Y-12989960D02*
X9891777Y-12970912D01*
X9891777Y-12970912D02*
X9891777Y-12951865D01*
X9891777Y-12951865D02*
X9901301Y-12932817D01*
X9901301Y-12932817D02*
X9920348Y-12923293D01*
X9920348Y-12923293D02*
X9967967Y-12923293D01*
X9967967Y-12923293D02*
X9987015Y-12913769D01*
X10082253Y-12866150D02*
X10082253Y-13066150D01*
X10082253Y-12875674D02*
X10101301Y-12866150D01*
X10101301Y-12866150D02*
X10139396Y-12866150D01*
X10139396Y-12866150D02*
X10158444Y-12875674D01*
X10158444Y-12875674D02*
X10167967Y-12885198D01*
X10167967Y-12885198D02*
X10177491Y-12904246D01*
X10177491Y-12904246D02*
X10177491Y-12961388D01*
X10177491Y-12961388D02*
X10167967Y-12980436D01*
X10167967Y-12980436D02*
X10158444Y-12989960D01*
X10158444Y-12989960D02*
X10139396Y-12999484D01*
X10139396Y-12999484D02*
X10101301Y-12999484D01*
X10101301Y-12999484D02*
X10082253Y-12989960D01*
X10263205Y-12980436D02*
X10272729Y-12989960D01*
X10272729Y-12989960D02*
X10263205Y-12999484D01*
X10263205Y-12999484D02*
X10253682Y-12989960D01*
X10253682Y-12989960D02*
X10263205Y-12980436D01*
X10263205Y-12980436D02*
X10263205Y-12999484D01*
X10263205Y-12875674D02*
X10272729Y-12885198D01*
X10272729Y-12885198D02*
X10263205Y-12894722D01*
X10263205Y-12894722D02*
X10253682Y-12885198D01*
X10253682Y-12885198D02*
X10263205Y-12875674D01*
X10263205Y-12875674D02*
X10263205Y-12894722D01*
X8431000Y-13228000D02*
X8631000Y-13428000D01*
X8631000Y-13228000D02*
X8431000Y-13428000D01*
X8872729Y-13219484D02*
X8996539Y-13219484D01*
X8996539Y-13219484D02*
X8929872Y-13295674D01*
X8929872Y-13295674D02*
X8958444Y-13295674D01*
X8958444Y-13295674D02*
X8977491Y-13305198D01*
X8977491Y-13305198D02*
X8987015Y-13314722D01*
X8987015Y-13314722D02*
X8996539Y-13333769D01*
X8996539Y-13333769D02*
X8996539Y-13381388D01*
X8996539Y-13381388D02*
X8987015Y-13400436D01*
X8987015Y-13400436D02*
X8977491Y-13409960D01*
X8977491Y-13409960D02*
X8958444Y-13419484D01*
X8958444Y-13419484D02*
X8901301Y-13419484D01*
X8901301Y-13419484D02*
X8882253Y-13409960D01*
X8882253Y-13409960D02*
X8872729Y-13400436D01*
X9082253Y-13400436D02*
X9091777Y-13409960D01*
X9091777Y-13409960D02*
X9082253Y-13419484D01*
X9082253Y-13419484D02*
X9072729Y-13409960D01*
X9072729Y-13409960D02*
X9082253Y-13400436D01*
X9082253Y-13400436D02*
X9082253Y-13419484D01*
X9167967Y-13238531D02*
X9177491Y-13229008D01*
X9177491Y-13229008D02*
X9196539Y-13219484D01*
X9196539Y-13219484D02*
X9244158Y-13219484D01*
X9244158Y-13219484D02*
X9263205Y-13229008D01*
X9263205Y-13229008D02*
X9272729Y-13238531D01*
X9272729Y-13238531D02*
X9282253Y-13257579D01*
X9282253Y-13257579D02*
X9282253Y-13276627D01*
X9282253Y-13276627D02*
X9272729Y-13305198D01*
X9272729Y-13305198D02*
X9158444Y-13419484D01*
X9158444Y-13419484D02*
X9282253Y-13419484D01*
X9406063Y-13219484D02*
X9425110Y-13219484D01*
X9425110Y-13219484D02*
X9444158Y-13229008D01*
X9444158Y-13229008D02*
X9453682Y-13238531D01*
X9453682Y-13238531D02*
X9463205Y-13257579D01*
X9463205Y-13257579D02*
X9472729Y-13295674D01*
X9472729Y-13295674D02*
X9472729Y-13343293D01*
X9472729Y-13343293D02*
X9463205Y-13381388D01*
X9463205Y-13381388D02*
X9453682Y-13400436D01*
X9453682Y-13400436D02*
X9444158Y-13409960D01*
X9444158Y-13409960D02*
X9425110Y-13419484D01*
X9425110Y-13419484D02*
X9406063Y-13419484D01*
X9406063Y-13419484D02*
X9387015Y-13409960D01*
X9387015Y-13409960D02*
X9377491Y-13400436D01*
X9377491Y-13400436D02*
X9367967Y-13381388D01*
X9367967Y-13381388D02*
X9358444Y-13343293D01*
X9358444Y-13343293D02*
X9358444Y-13295674D01*
X9358444Y-13295674D02*
X9367967Y-13257579D01*
X9367967Y-13257579D02*
X9377491Y-13238531D01*
X9377491Y-13238531D02*
X9387015Y-13229008D01*
X9387015Y-13229008D02*
X9406063Y-13219484D01*
X9596539Y-13219484D02*
X9615586Y-13219484D01*
X9615586Y-13219484D02*
X9634634Y-13229008D01*
X9634634Y-13229008D02*
X9644158Y-13238531D01*
X9644158Y-13238531D02*
X9653682Y-13257579D01*
X9653682Y-13257579D02*
X9663205Y-13295674D01*
X9663205Y-13295674D02*
X9663205Y-13343293D01*
X9663205Y-13343293D02*
X9653682Y-13381388D01*
X9653682Y-13381388D02*
X9644158Y-13400436D01*
X9644158Y-13400436D02*
X9634634Y-13409960D01*
X9634634Y-13409960D02*
X9615586Y-13419484D01*
X9615586Y-13419484D02*
X9596539Y-13419484D01*
X9596539Y-13419484D02*
X9577491Y-13409960D01*
X9577491Y-13409960D02*
X9567967Y-13400436D01*
X9567967Y-13400436D02*
X9558444Y-13381388D01*
X9558444Y-13381388D02*
X9548920Y-13343293D01*
X9548920Y-13343293D02*
X9548920Y-13295674D01*
X9548920Y-13295674D02*
X9558444Y-13257579D01*
X9558444Y-13257579D02*
X9567967Y-13238531D01*
X9567967Y-13238531D02*
X9577491Y-13229008D01*
X9577491Y-13229008D02*
X9596539Y-13219484D01*
X9748920Y-13419484D02*
X9748920Y-13286150D01*
X9748920Y-13305198D02*
X9758444Y-13295674D01*
X9758444Y-13295674D02*
X9777491Y-13286150D01*
X9777491Y-13286150D02*
X9806063Y-13286150D01*
X9806063Y-13286150D02*
X9825110Y-13295674D01*
X9825110Y-13295674D02*
X9834634Y-13314722D01*
X9834634Y-13314722D02*
X9834634Y-13419484D01*
X9834634Y-13314722D02*
X9844158Y-13295674D01*
X9844158Y-13295674D02*
X9863205Y-13286150D01*
X9863205Y-13286150D02*
X9891777Y-13286150D01*
X9891777Y-13286150D02*
X9910825Y-13295674D01*
X9910825Y-13295674D02*
X9920348Y-13314722D01*
X9920348Y-13314722D02*
X9920348Y-13419484D01*
X10015586Y-13419484D02*
X10015586Y-13286150D01*
X10015586Y-13305198D02*
X10025110Y-13295674D01*
X10025110Y-13295674D02*
X10044158Y-13286150D01*
X10044158Y-13286150D02*
X10072729Y-13286150D01*
X10072729Y-13286150D02*
X10091777Y-13295674D01*
X10091777Y-13295674D02*
X10101301Y-13314722D01*
X10101301Y-13314722D02*
X10101301Y-13419484D01*
X10101301Y-13314722D02*
X10110825Y-13295674D01*
X10110825Y-13295674D02*
X10129872Y-13286150D01*
X10129872Y-13286150D02*
X10158444Y-13286150D01*
X10158444Y-13286150D02*
X10177491Y-13295674D01*
X10177491Y-13295674D02*
X10187015Y-13314722D01*
X10187015Y-13314722D02*
X10187015Y-13419484D01*
X10577491Y-13209960D02*
X10406063Y-13467103D01*
X10834634Y-13219484D02*
X10853682Y-13219484D01*
X10853682Y-13219484D02*
X10872729Y-13229008D01*
X10872729Y-13229008D02*
X10882253Y-13238531D01*
X10882253Y-13238531D02*
X10891777Y-13257579D01*
X10891777Y-13257579D02*
X10901301Y-13295674D01*
X10901301Y-13295674D02*
X10901301Y-13343293D01*
X10901301Y-13343293D02*
X10891777Y-13381388D01*
X10891777Y-13381388D02*
X10882253Y-13400436D01*
X10882253Y-13400436D02*
X10872729Y-13409960D01*
X10872729Y-13409960D02*
X10853682Y-13419484D01*
X10853682Y-13419484D02*
X10834634Y-13419484D01*
X10834634Y-13419484D02*
X10815587Y-13409960D01*
X10815587Y-13409960D02*
X10806063Y-13400436D01*
X10806063Y-13400436D02*
X10796539Y-13381388D01*
X10796539Y-13381388D02*
X10787015Y-13343293D01*
X10787015Y-13343293D02*
X10787015Y-13295674D01*
X10787015Y-13295674D02*
X10796539Y-13257579D01*
X10796539Y-13257579D02*
X10806063Y-13238531D01*
X10806063Y-13238531D02*
X10815587Y-13229008D01*
X10815587Y-13229008D02*
X10834634Y-13219484D01*
X10987015Y-13400436D02*
X10996539Y-13409960D01*
X10996539Y-13409960D02*
X10987015Y-13419484D01*
X10987015Y-13419484D02*
X10977491Y-13409960D01*
X10977491Y-13409960D02*
X10987015Y-13400436D01*
X10987015Y-13400436D02*
X10987015Y-13419484D01*
X11187015Y-13419484D02*
X11072729Y-13419484D01*
X11129872Y-13419484D02*
X11129872Y-13219484D01*
X11129872Y-13219484D02*
X11110825Y-13248055D01*
X11110825Y-13248055D02*
X11091777Y-13267103D01*
X11091777Y-13267103D02*
X11072729Y-13276627D01*
X11263206Y-13238531D02*
X11272729Y-13229008D01*
X11272729Y-13229008D02*
X11291777Y-13219484D01*
X11291777Y-13219484D02*
X11339396Y-13219484D01*
X11339396Y-13219484D02*
X11358444Y-13229008D01*
X11358444Y-13229008D02*
X11367967Y-13238531D01*
X11367967Y-13238531D02*
X11377491Y-13257579D01*
X11377491Y-13257579D02*
X11377491Y-13276627D01*
X11377491Y-13276627D02*
X11367967Y-13305198D01*
X11367967Y-13305198D02*
X11253682Y-13419484D01*
X11253682Y-13419484D02*
X11377491Y-13419484D01*
X11548920Y-13219484D02*
X11510825Y-13219484D01*
X11510825Y-13219484D02*
X11491777Y-13229008D01*
X11491777Y-13229008D02*
X11482253Y-13238531D01*
X11482253Y-13238531D02*
X11463206Y-13267103D01*
X11463206Y-13267103D02*
X11453682Y-13305198D01*
X11453682Y-13305198D02*
X11453682Y-13381388D01*
X11453682Y-13381388D02*
X11463206Y-13400436D01*
X11463206Y-13400436D02*
X11472729Y-13409960D01*
X11472729Y-13409960D02*
X11491777Y-13419484D01*
X11491777Y-13419484D02*
X11529872Y-13419484D01*
X11529872Y-13419484D02*
X11548920Y-13409960D01*
X11548920Y-13409960D02*
X11558444Y-13400436D01*
X11558444Y-13400436D02*
X11567967Y-13381388D01*
X11567967Y-13381388D02*
X11567967Y-13333769D01*
X11567967Y-13333769D02*
X11558444Y-13314722D01*
X11558444Y-13314722D02*
X11548920Y-13305198D01*
X11548920Y-13305198D02*
X11529872Y-13295674D01*
X11529872Y-13295674D02*
X11491777Y-13295674D01*
X11491777Y-13295674D02*
X11472729Y-13305198D01*
X11472729Y-13305198D02*
X11463206Y-13314722D01*
X11463206Y-13314722D02*
X11453682Y-13333769D01*
X11691777Y-13219484D02*
X11710825Y-13219484D01*
X11710825Y-13219484D02*
X11729872Y-13229008D01*
X11729872Y-13229008D02*
X11739396Y-13238531D01*
X11739396Y-13238531D02*
X11748920Y-13257579D01*
X11748920Y-13257579D02*
X11758444Y-13295674D01*
X11758444Y-13295674D02*
X11758444Y-13343293D01*
X11758444Y-13343293D02*
X11748920Y-13381388D01*
X11748920Y-13381388D02*
X11739396Y-13400436D01*
X11739396Y-13400436D02*
X11729872Y-13409960D01*
X11729872Y-13409960D02*
X11710825Y-13419484D01*
X11710825Y-13419484D02*
X11691777Y-13419484D01*
X11691777Y-13419484D02*
X11672729Y-13409960D01*
X11672729Y-13409960D02*
X11663206Y-13400436D01*
X11663206Y-13400436D02*
X11653682Y-13381388D01*
X11653682Y-13381388D02*
X11644158Y-13343293D01*
X11644158Y-13343293D02*
X11644158Y-13295674D01*
X11644158Y-13295674D02*
X11653682Y-13257579D01*
X11653682Y-13257579D02*
X11663206Y-13238531D01*
X11663206Y-13238531D02*
X11672729Y-13229008D01*
X11672729Y-13229008D02*
X11691777Y-13219484D01*
X11834634Y-13219484D02*
X11834634Y-13257579D01*
X11910825Y-13219484D02*
X11910825Y-13257579D01*
X12206063Y-13495674D02*
X12196539Y-13486150D01*
X12196539Y-13486150D02*
X12177491Y-13457579D01*
X12177491Y-13457579D02*
X12167968Y-13438531D01*
X12167968Y-13438531D02*
X12158444Y-13409960D01*
X12158444Y-13409960D02*
X12148920Y-13362341D01*
X12148920Y-13362341D02*
X12148920Y-13324246D01*
X12148920Y-13324246D02*
X12158444Y-13276627D01*
X12158444Y-13276627D02*
X12167968Y-13248055D01*
X12167968Y-13248055D02*
X12177491Y-13229008D01*
X12177491Y-13229008D02*
X12196539Y-13200436D01*
X12196539Y-13200436D02*
X12206063Y-13190912D01*
X12263206Y-13219484D02*
X12387015Y-13219484D01*
X12387015Y-13219484D02*
X12320348Y-13295674D01*
X12320348Y-13295674D02*
X12348920Y-13295674D01*
X12348920Y-13295674D02*
X12367968Y-13305198D01*
X12367968Y-13305198D02*
X12377491Y-13314722D01*
X12377491Y-13314722D02*
X12387015Y-13333769D01*
X12387015Y-13333769D02*
X12387015Y-13381388D01*
X12387015Y-13381388D02*
X12377491Y-13400436D01*
X12377491Y-13400436D02*
X12367968Y-13409960D01*
X12367968Y-13409960D02*
X12348920Y-13419484D01*
X12348920Y-13419484D02*
X12291777Y-13419484D01*
X12291777Y-13419484D02*
X12272729Y-13409960D01*
X12272729Y-13409960D02*
X12263206Y-13400436D01*
X12625110Y-13419484D02*
X12625110Y-13219484D01*
X12710825Y-13419484D02*
X12710825Y-13314722D01*
X12710825Y-13314722D02*
X12701301Y-13295674D01*
X12701301Y-13295674D02*
X12682253Y-13286150D01*
X12682253Y-13286150D02*
X12653682Y-13286150D01*
X12653682Y-13286150D02*
X12634634Y-13295674D01*
X12634634Y-13295674D02*
X12625110Y-13305198D01*
X12834634Y-13419484D02*
X12815587Y-13409960D01*
X12815587Y-13409960D02*
X12806063Y-13400436D01*
X12806063Y-13400436D02*
X12796539Y-13381388D01*
X12796539Y-13381388D02*
X12796539Y-13324246D01*
X12796539Y-13324246D02*
X12806063Y-13305198D01*
X12806063Y-13305198D02*
X12815587Y-13295674D01*
X12815587Y-13295674D02*
X12834634Y-13286150D01*
X12834634Y-13286150D02*
X12863206Y-13286150D01*
X12863206Y-13286150D02*
X12882253Y-13295674D01*
X12882253Y-13295674D02*
X12891777Y-13305198D01*
X12891777Y-13305198D02*
X12901301Y-13324246D01*
X12901301Y-13324246D02*
X12901301Y-13381388D01*
X12901301Y-13381388D02*
X12891777Y-13400436D01*
X12891777Y-13400436D02*
X12882253Y-13409960D01*
X12882253Y-13409960D02*
X12863206Y-13419484D01*
X12863206Y-13419484D02*
X12834634Y-13419484D01*
X13015587Y-13419484D02*
X12996539Y-13409960D01*
X12996539Y-13409960D02*
X12987015Y-13390912D01*
X12987015Y-13390912D02*
X12987015Y-13219484D01*
X13167968Y-13409960D02*
X13148920Y-13419484D01*
X13148920Y-13419484D02*
X13110825Y-13419484D01*
X13110825Y-13419484D02*
X13091777Y-13409960D01*
X13091777Y-13409960D02*
X13082253Y-13390912D01*
X13082253Y-13390912D02*
X13082253Y-13314722D01*
X13082253Y-13314722D02*
X13091777Y-13295674D01*
X13091777Y-13295674D02*
X13110825Y-13286150D01*
X13110825Y-13286150D02*
X13148920Y-13286150D01*
X13148920Y-13286150D02*
X13167968Y-13295674D01*
X13167968Y-13295674D02*
X13177491Y-13314722D01*
X13177491Y-13314722D02*
X13177491Y-13333769D01*
X13177491Y-13333769D02*
X13082253Y-13352817D01*
X13253682Y-13409960D02*
X13272730Y-13419484D01*
X13272730Y-13419484D02*
X13310825Y-13419484D01*
X13310825Y-13419484D02*
X13329872Y-13409960D01*
X13329872Y-13409960D02*
X13339396Y-13390912D01*
X13339396Y-13390912D02*
X13339396Y-13381388D01*
X13339396Y-13381388D02*
X13329872Y-13362341D01*
X13329872Y-13362341D02*
X13310825Y-13352817D01*
X13310825Y-13352817D02*
X13282253Y-13352817D01*
X13282253Y-13352817D02*
X13263206Y-13343293D01*
X13263206Y-13343293D02*
X13253682Y-13324246D01*
X13253682Y-13324246D02*
X13253682Y-13314722D01*
X13253682Y-13314722D02*
X13263206Y-13295674D01*
X13263206Y-13295674D02*
X13282253Y-13286150D01*
X13282253Y-13286150D02*
X13310825Y-13286150D01*
X13310825Y-13286150D02*
X13329872Y-13295674D01*
X13406063Y-13495674D02*
X13415587Y-13486150D01*
X13415587Y-13486150D02*
X13434634Y-13457579D01*
X13434634Y-13457579D02*
X13444158Y-13438531D01*
X13444158Y-13438531D02*
X13453682Y-13409960D01*
X13453682Y-13409960D02*
X13463206Y-13362341D01*
X13463206Y-13362341D02*
X13463206Y-13324246D01*
X13463206Y-13324246D02*
X13453682Y-13276627D01*
X13453682Y-13276627D02*
X13444158Y-13248055D01*
X13444158Y-13248055D02*
X13434634Y-13229008D01*
X13434634Y-13229008D02*
X13415587Y-13200436D01*
X13415587Y-13200436D02*
X13406063Y-13190912D01*
X13767968Y-13495674D02*
X13758444Y-13486150D01*
X13758444Y-13486150D02*
X13739396Y-13457579D01*
X13739396Y-13457579D02*
X13729872Y-13438531D01*
X13729872Y-13438531D02*
X13720349Y-13409960D01*
X13720349Y-13409960D02*
X13710825Y-13362341D01*
X13710825Y-13362341D02*
X13710825Y-13324246D01*
X13710825Y-13324246D02*
X13720349Y-13276627D01*
X13720349Y-13276627D02*
X13729872Y-13248055D01*
X13729872Y-13248055D02*
X13739396Y-13229008D01*
X13739396Y-13229008D02*
X13758444Y-13200436D01*
X13758444Y-13200436D02*
X13767968Y-13190912D01*
X13844158Y-13286150D02*
X13844158Y-13419484D01*
X13844158Y-13305198D02*
X13853682Y-13295674D01*
X13853682Y-13295674D02*
X13872730Y-13286150D01*
X13872730Y-13286150D02*
X13901301Y-13286150D01*
X13901301Y-13286150D02*
X13920349Y-13295674D01*
X13920349Y-13295674D02*
X13929872Y-13314722D01*
X13929872Y-13314722D02*
X13929872Y-13419484D01*
X14053682Y-13419484D02*
X14034634Y-13409960D01*
X14034634Y-13409960D02*
X14025111Y-13400436D01*
X14025111Y-13400436D02*
X14015587Y-13381388D01*
X14015587Y-13381388D02*
X14015587Y-13324246D01*
X14015587Y-13324246D02*
X14025111Y-13305198D01*
X14025111Y-13305198D02*
X14034634Y-13295674D01*
X14034634Y-13295674D02*
X14053682Y-13286150D01*
X14053682Y-13286150D02*
X14082253Y-13286150D01*
X14082253Y-13286150D02*
X14101301Y-13295674D01*
X14101301Y-13295674D02*
X14110825Y-13305198D01*
X14110825Y-13305198D02*
X14120349Y-13324246D01*
X14120349Y-13324246D02*
X14120349Y-13381388D01*
X14120349Y-13381388D02*
X14110825Y-13400436D01*
X14110825Y-13400436D02*
X14101301Y-13409960D01*
X14101301Y-13409960D02*
X14082253Y-13419484D01*
X14082253Y-13419484D02*
X14053682Y-13419484D01*
X14177492Y-13286150D02*
X14253682Y-13286150D01*
X14206063Y-13219484D02*
X14206063Y-13390912D01*
X14206063Y-13390912D02*
X14215587Y-13409960D01*
X14215587Y-13409960D02*
X14234634Y-13419484D01*
X14234634Y-13419484D02*
X14253682Y-13419484D01*
X14472730Y-13286150D02*
X14472730Y-13486150D01*
X14472730Y-13295674D02*
X14491777Y-13286150D01*
X14491777Y-13286150D02*
X14529873Y-13286150D01*
X14529873Y-13286150D02*
X14548920Y-13295674D01*
X14548920Y-13295674D02*
X14558444Y-13305198D01*
X14558444Y-13305198D02*
X14567968Y-13324246D01*
X14567968Y-13324246D02*
X14567968Y-13381388D01*
X14567968Y-13381388D02*
X14558444Y-13400436D01*
X14558444Y-13400436D02*
X14548920Y-13409960D01*
X14548920Y-13409960D02*
X14529873Y-13419484D01*
X14529873Y-13419484D02*
X14491777Y-13419484D01*
X14491777Y-13419484D02*
X14472730Y-13409960D01*
X14682253Y-13419484D02*
X14663206Y-13409960D01*
X14663206Y-13409960D02*
X14653682Y-13390912D01*
X14653682Y-13390912D02*
X14653682Y-13219484D01*
X14844158Y-13419484D02*
X14844158Y-13314722D01*
X14844158Y-13314722D02*
X14834634Y-13295674D01*
X14834634Y-13295674D02*
X14815587Y-13286150D01*
X14815587Y-13286150D02*
X14777492Y-13286150D01*
X14777492Y-13286150D02*
X14758444Y-13295674D01*
X14844158Y-13409960D02*
X14825111Y-13419484D01*
X14825111Y-13419484D02*
X14777492Y-13419484D01*
X14777492Y-13419484D02*
X14758444Y-13409960D01*
X14758444Y-13409960D02*
X14748920Y-13390912D01*
X14748920Y-13390912D02*
X14748920Y-13371865D01*
X14748920Y-13371865D02*
X14758444Y-13352817D01*
X14758444Y-13352817D02*
X14777492Y-13343293D01*
X14777492Y-13343293D02*
X14825111Y-13343293D01*
X14825111Y-13343293D02*
X14844158Y-13333769D01*
X14910825Y-13286150D02*
X14987015Y-13286150D01*
X14939396Y-13219484D02*
X14939396Y-13390912D01*
X14939396Y-13390912D02*
X14948920Y-13409960D01*
X14948920Y-13409960D02*
X14967968Y-13419484D01*
X14967968Y-13419484D02*
X14987015Y-13419484D01*
X15129873Y-13409960D02*
X15110825Y-13419484D01*
X15110825Y-13419484D02*
X15072730Y-13419484D01*
X15072730Y-13419484D02*
X15053682Y-13409960D01*
X15053682Y-13409960D02*
X15044158Y-13390912D01*
X15044158Y-13390912D02*
X15044158Y-13314722D01*
X15044158Y-13314722D02*
X15053682Y-13295674D01*
X15053682Y-13295674D02*
X15072730Y-13286150D01*
X15072730Y-13286150D02*
X15110825Y-13286150D01*
X15110825Y-13286150D02*
X15129873Y-13295674D01*
X15129873Y-13295674D02*
X15139396Y-13314722D01*
X15139396Y-13314722D02*
X15139396Y-13333769D01*
X15139396Y-13333769D02*
X15044158Y-13352817D01*
X15310825Y-13419484D02*
X15310825Y-13219484D01*
X15310825Y-13409960D02*
X15291777Y-13419484D01*
X15291777Y-13419484D02*
X15253682Y-13419484D01*
X15253682Y-13419484D02*
X15234634Y-13409960D01*
X15234634Y-13409960D02*
X15225111Y-13400436D01*
X15225111Y-13400436D02*
X15215587Y-13381388D01*
X15215587Y-13381388D02*
X15215587Y-13324246D01*
X15215587Y-13324246D02*
X15225111Y-13305198D01*
X15225111Y-13305198D02*
X15234634Y-13295674D01*
X15234634Y-13295674D02*
X15253682Y-13286150D01*
X15253682Y-13286150D02*
X15291777Y-13286150D01*
X15291777Y-13286150D02*
X15310825Y-13295674D01*
X15387015Y-13495674D02*
X15396539Y-13486150D01*
X15396539Y-13486150D02*
X15415587Y-13457579D01*
X15415587Y-13457579D02*
X15425111Y-13438531D01*
X15425111Y-13438531D02*
X15434634Y-13409960D01*
X15434634Y-13409960D02*
X15444158Y-13362341D01*
X15444158Y-13362341D02*
X15444158Y-13324246D01*
X15444158Y-13324246D02*
X15434634Y-13276627D01*
X15434634Y-13276627D02*
X15425111Y-13248055D01*
X15425111Y-13248055D02*
X15415587Y-13229008D01*
X15415587Y-13229008D02*
X15396539Y-13200436D01*
X15396539Y-13200436D02*
X15387015Y-13190912D01*
M02*

View File

@@ -0,0 +1,19 @@
M48
; DRILL file {KiCad 7.0.5} date Wed Sep 11 17:05:49 2024
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2024-09-11T17:05:49+02:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,7.0.5
; #@! TF.FileFunction,NonPlated,1,2,NPTH
FMAT,2
INCH
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
T1C0.1260
%
G90
G05
T1
X3.55Y-4.825
X4.775Y-4.825
X4.825Y-1.6
T0
M30

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,101 @@
M48
; DRILL file {KiCad 7.0.5} date Wed Sep 11 17:05:49 2024
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2024-09-11T17:05:49+02:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,7.0.5
; #@! TF.FileFunction,Plated,1,2,PTH
FMAT,2
INCH
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T1C0.0157
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T2C0.0315
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T3C0.0374
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T4C0.0394
%
G90
G05
T1
X3.76Y-2.74
X3.79Y-4.03
X4.06Y-3.98
X4.22Y-3.98
X4.38Y-3.873
X4.69Y-4.04
X4.87Y-4.1599
X4.87Y-4.22
X4.8727Y-4.2824
X4.91Y-4.27
X4.94Y-2.93
X4.94Y-4.18
X4.9622Y-3.9015
X4.9727Y-2.9585
X4.99Y-3.93
X4.9953Y-3.873
X5.0055Y-2.9803
X5.01Y-3.8
X5.0306Y-3.0107
X5.0363Y-4.236
X5.0549Y-4.3977
X5.09Y-4.38
X5.0933Y-3.0286
X5.1093Y-2.9926
X5.1415Y-2.97
X5.15Y-4.3994
X5.17Y-2.94
X5.22Y-4.06
X5.24Y-3.8
X5.26Y-4.09
X5.3Y-3.94
X5.3Y-4.15
X5.3Y-4.23
X5.3362Y-3.8955
X5.3398Y-3.9395
X5.39Y-3.62
X5.4132Y-4.69
X5.43Y-4.15
X5.44Y-3.92
X5.49Y-3.85
X5.49Y-4.02
X5.54Y-4.49
X5.55Y-4.2
X5.57Y-4.66
X5.6Y-4.3817
X5.6415Y-4.364
X5.67Y-4.2
X5.67Y-4.2715
X5.69Y-4.4
X5.69Y-4.49
X5.6914Y-4.6694
X5.6982Y-4.5673
X5.7186Y-4.3672
X5.72Y-4.6
X5.7261Y-4.3285
T2
X4.7135Y-4.5
X4.9057Y-4.5
X5.3404Y-4.5904
X5.3404Y-4.6904
X5.3404Y-4.7904
X5.3404Y-4.8904
X5.51Y-2.56
X5.51Y-2.6584
X5.62Y-3.8016
X5.62Y-3.9
X5.6404Y-4.5904
X5.6404Y-4.6904
X5.6404Y-4.7904
X5.6404Y-4.8904
T3
X5.52Y-1.92
X5.52Y-2.0184
X5.52Y-2.1169
X5.52Y-2.2153
X5.52Y-2.3137
T4
X5.65Y-3.42
X5.65Y-3.6169
T0
M30

View File

@@ -0,0 +1 @@
Ref,Val,Package,PosX,PosY,Rot,Side
1 Ref Val Package PosX PosY Rot Side

View File

@@ -0,0 +1,6 @@
### Footprint positions - created on Wed Sep 11 18:53:40 2024 ###
### Printed by KiCad version 7.0.5
## Unit = mm, Angle = deg.
## Side : bottom
# Ref Val Package PosX PosY Rot Side
## End

View File

@@ -0,0 +1,127 @@
{
"Header": {
"GenerationSoftware": {
"Vendor": "KiCad",
"Application": "Pcbnew",
"Version": "7.0.5"
},
"CreationDate": "2024-09-11T17:05:46+02:00"
},
"GeneralSpecs": {
"ProjectId": {
"Name": "ModuleController",
"GUID": "4d6f6475-6c65-4436-9f6e-74726f6c6c65",
"Revision": "rev?"
},
"Size": {
"X": 68.335,
"Y": 90.1
},
"LayerNumber": 2,
"BoardThickness": 1.6,
"Finish": "None"
},
"DesignRules": [
{
"Layers": "Outer",
"PadToPad": 0.2,
"PadToTrack": 0.2,
"TrackToTrack": 0.2,
"MinLineWidth": 0.25,
"TrackToRegion": 0.5,
"RegionToRegion": 0.5
}
],
"FilesAttributes": [
{
"Path": "ModuleController-F_Cu.gbr",
"FileFunction": "Copper,L1,Top",
"FilePolarity": "Positive"
},
{
"Path": "ModuleController-B_Cu.gbr",
"FileFunction": "Copper,L2,Bot",
"FilePolarity": "Positive"
},
{
"Path": "ModuleController-F_Paste.gbr",
"FileFunction": "SolderPaste,Top",
"FilePolarity": "Positive"
},
{
"Path": "ModuleController-B_Paste.gbr",
"FileFunction": "SolderPaste,Bot",
"FilePolarity": "Positive"
},
{
"Path": "ModuleController-F_Silkscreen.gbr",
"FileFunction": "Legend,Top",
"FilePolarity": "Positive"
},
{
"Path": "ModuleController-B_Silkscreen.gbr",
"FileFunction": "Legend,Bot",
"FilePolarity": "Positive"
},
{
"Path": "ModuleController-F_Mask.gbr",
"FileFunction": "SolderMask,Top",
"FilePolarity": "Negative"
},
{
"Path": "ModuleController-B_Mask.gbr",
"FileFunction": "SolderMask,Bot",
"FilePolarity": "Negative"
},
{
"Path": "ModuleController-Edge_Cuts.gbr",
"FileFunction": "Profile",
"FilePolarity": "Positive"
}
],
"MaterialStackup": [
{
"Type": "Legend",
"Name": "Top Silk Screen"
},
{
"Type": "SolderPaste",
"Name": "Top Solder Paste"
},
{
"Type": "SolderMask",
"Thickness": 0.01,
"Name": "Top Solder Mask"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "F.Cu"
},
{
"Type": "Dielectric",
"Thickness": 1.51,
"Material": "FR4",
"Name": "F.Cu/B.Cu",
"Notes": "Type: dielectric layer 1 (from F.Cu to B.Cu)"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "B.Cu"
},
{
"Type": "SolderMask",
"Thickness": 0.01,
"Name": "Bottom Solder Mask"
},
{
"Type": "SolderPaste",
"Name": "Bottom Solder Paste"
},
{
"Type": "Legend",
"Name": "Bottom Silk Screen"
}
]
}

View File

@@ -0,0 +1,18 @@
Ref,Val,Package,PosX,PosY,Rot,Side
"C1","10u 35V","CP_Radial_D6.3mm_P2.50mm",139.954000,-65.024000,-90.000000,top
"C2","10u 15V","CP_Radial_D5.0mm_P2.50mm",142.748000,-99.060000,90.000000,top
"C3","22p","C_0805_2012Metric",130.048000,-116.332000,180.000000,top
"C4","22p","C_0805_2012Metric",130.048000,-114.046000,180.000000,top
"C5","100n","C_0805_2012Metric",132.842000,-106.680000,-90.000000,top
"C6","100n","C_0805_2012Metric",118.430000,-107.188000,0.000000,top
"F1","Polyfuse 10ma/20mA","C_Disc_D7.5mm_W2.5mm_P5.00mm",143.510000,-91.868000,90.000000,top
"J1","JST05_StepperMotor","JST_XH_B5B-XH-A_1x05_P2.50mm_Vertical",140.208000,-48.768000,-90.000000,top
"J6","Conn_02x08_Top_Bottom","Card Edge 16 power",150.175000,-119.380000,90.000000,top
"R1","10k","R_0805_2012Metric",132.484500,-121.666000,180.000000,top
"R2","10k","R_0805_2012Metric",139.549500,-88.744000,0.000000,top
"R3","4k7","R_0805_2012Metric",139.549500,-91.694000,0.000000,top
"U1","ULN2003","SOIC-16W_5.3x10.2mm_P1.27mm",130.048000,-61.214000,90.000000,top
"U2","A1101ELHL","SOT-23W",95.000000,-71.810000,0.000000,top
"U3","SN75176AP","DIP-8_W7.62mm",135.646000,-116.596000,0.000000,top
"U4","ATmega8A-A","TQFP-32_7x7mm_P0.8mm",125.838000,-105.986000,0.000000,top
"Y1","16MHz","Crystal_HC49-U_Vertical",119.724000,-114.300000,0.000000,top
1 Ref Val Package PosX PosY Rot Side
2 C1 10u 35V CP_Radial_D6.3mm_P2.50mm 139.954000 -65.024000 -90.000000 top
3 C2 10u 15V CP_Radial_D5.0mm_P2.50mm 142.748000 -99.060000 90.000000 top
4 C3 22p C_0805_2012Metric 130.048000 -116.332000 180.000000 top
5 C4 22p C_0805_2012Metric 130.048000 -114.046000 180.000000 top
6 C5 100n C_0805_2012Metric 132.842000 -106.680000 -90.000000 top
7 C6 100n C_0805_2012Metric 118.430000 -107.188000 0.000000 top
8 F1 Polyfuse 10ma/20mA C_Disc_D7.5mm_W2.5mm_P5.00mm 143.510000 -91.868000 90.000000 top
9 J1 JST05_StepperMotor JST_XH_B5B-XH-A_1x05_P2.50mm_Vertical 140.208000 -48.768000 -90.000000 top
10 J6 Conn_02x08_Top_Bottom Card Edge 16 power 150.175000 -119.380000 90.000000 top
11 R1 10k R_0805_2012Metric 132.484500 -121.666000 180.000000 top
12 R2 10k R_0805_2012Metric 139.549500 -88.744000 0.000000 top
13 R3 4k7 R_0805_2012Metric 139.549500 -91.694000 0.000000 top
14 U1 ULN2003 SOIC-16W_5.3x10.2mm_P1.27mm 130.048000 -61.214000 90.000000 top
15 U2 A1101ELHL SOT-23W 95.000000 -71.810000 0.000000 top
16 U3 SN75176AP DIP-8_W7.62mm 135.646000 -116.596000 0.000000 top
17 U4 ATmega8A-A TQFP-32_7x7mm_P0.8mm 125.838000 -105.986000 0.000000 top
18 Y1 16MHz Crystal_HC49-U_Vertical 119.724000 -114.300000 0.000000 top

View File

@@ -0,0 +1,23 @@
### Footprint positions - created on Wed Sep 11 18:53:39 2024 ###
### Printed by KiCad version 7.0.5
## Unit = mm, Angle = deg.
## Side : top
# Ref Val Package PosX PosY Rot Side
C1 10u_35V CP_Radial_D6.3mm_P2.50mm 139.9540 -65.0240 -90.0000 top
C2 10u_15V CP_Radial_D5.0mm_P2.50mm 142.7480 -99.0600 90.0000 top
C3 22p C_0805_2012Metric 130.0480 -116.3320 180.0000 top
C4 22p C_0805_2012Metric 130.0480 -114.0460 180.0000 top
C5 100n C_0805_2012Metric 132.8420 -106.6800 -90.0000 top
C6 100n C_0805_2012Metric 118.4300 -107.1880 0.0000 top
F1 Polyfuse_10ma/20mA C_Disc_D7.5mm_W2.5mm_P5.00mm 143.5100 -91.8680 90.0000 top
J1 JST05_StepperMotor JST_XH_B5B-XH-A_1x05_P2.50mm_Vertical 140.2080 -48.7680 -90.0000 top
J6 Conn_02x08_Top_Bottom Card_Edge_16_power 150.1750 -119.3800 90.0000 top
R1 10k R_0805_2012Metric 132.4845 -121.6660 180.0000 top
R2 10k R_0805_2012Metric 139.5495 -88.7440 0.0000 top
R3 4k7 R_0805_2012Metric 139.5495 -91.6940 0.0000 top
U1 ULN2003 SOIC-16W_5.3x10.2mm_P1.27mm 130.0480 -61.2140 90.0000 top
U2 A1101ELHL SOT-23W 95.0000 -71.8100 0.0000 top
U3 SN75176AP DIP-8_W7.62mm 135.6460 -116.5960 0.0000 top
U4 ATmega8A-A TQFP-32_7x7mm_P0.8mm 125.8380 -105.9860 0.0000 top
Y1 16MHz Crystal_HC49-U_Vertical 119.7240 -114.3000 0.0000 top
## End

View File

@@ -0,0 +1,17 @@
"Id";"Designator";"Footprint";"Quantity";"Designation";"Supplier and ref";
1;"R3";"R_0805_2012Metric";1;"4k7";;;
2;"R2,R1";"R_0805_2012Metric";2;"10k";;;
3;"F1";"C_Disc_D7.5mm_W2.5mm_P5.00mm";1;"Polyfuse 10ma/20mA";;;
4;"C6,C5";"C_0805_2012Metric";2;"100n";;;
5;"U4";"TQFP-32_7x7mm_P0.8mm";1;"ATmega8A-A";;;
6;"U2";"SOT-23W";1;"A1101ELHL";;;
7;"TP9,TP8,TP7";"TestPoint_Pad_D2.0mm";3;"COM";;;
8;"H3,H2,H1";"MountingHole_3.2mm_M3";3;"MountingHole";;;
9;"J6";"Card Edge 16 power";1;"Conn_02x08_Top_Bottom";;;
10;"J1";"JST_XH_B5B-XH-A_1x05_P2.50mm_Vertical";1;"JST05_StepperMotor";;;
11;"C2";"CP_Radial_D5.0mm_P2.50mm";1;"10u 15V";;;
12;"C3,C4";"C_0805_2012Metric";2;"22p";;;
13;"Y1";"Crystal_HC49-U_Vertical";1;"16MHz";;;
14;"C1";"CP_Radial_D6.3mm_P2.50mm";1;"10u 35V";;;
15;"U1";"SOIC-16W_5.3x10.2mm_P1.27mm";1;"ULN2003";;;
16;"U3";"DIP-8_W7.62mm";1;"SN75176AP";;;
1 Id Designator Footprint Quantity Designation Supplier and ref
2 1 R3 R_0805_2012Metric 1 4k7
3 2 R2,R1 R_0805_2012Metric 2 10k
4 3 F1 C_Disc_D7.5mm_W2.5mm_P5.00mm 1 Polyfuse 10ma/20mA
5 4 C6,C5 C_0805_2012Metric 2 100n
6 5 U4 TQFP-32_7x7mm_P0.8mm 1 ATmega8A-A
7 6 U2 SOT-23W 1 A1101ELHL
8 7 TP9,TP8,TP7 TestPoint_Pad_D2.0mm 3 COM
9 8 H3,H2,H1 MountingHole_3.2mm_M3 3 MountingHole
10 9 J6 Card Edge 16 power 1 Conn_02x08_Top_Bottom
11 10 J1 JST_XH_B5B-XH-A_1x05_P2.50mm_Vertical 1 JST05_StepperMotor
12 11 C2 CP_Radial_D5.0mm_P2.50mm 1 10u 15V
13 12 C3,C4 C_0805_2012Metric 2 22p
14 13 Y1 Crystal_HC49-U_Vertical 1 16MHz
15 14 C1 CP_Radial_D6.3mm_P2.50mm 1 10u 35V
16 15 U1 SOIC-16W_5.3x10.2mm_P1.27mm 1 ULN2003
17 16 U3 DIP-8_W7.62mm 1 SN75176AP

64025
ModuleController/Module.step Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
{
"board": {
"active_layer": 31,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": false,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36,
39,
40
],
"visible_layers": "ffdffff_ffffffff",
"zone_display_mode": 1
},
"git": {
"repo_password": "",
"repo_type": "",
"repo_username": "",
"ssh_key": ""
},
"meta": {
"filename": "ModuleController.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@@ -0,0 +1,600 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.15,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "ignore",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.0,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [
0.0,
0.6
],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "ModuleController.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "ModuleController.step",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"name": "Grouped By Value",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"4662523f-e8f9-4cfd-931a-1a77b7596ef8",
"Root"
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

94389
ModuleController/fp-info-cache Executable file

File diff suppressed because it is too large Load Diff

35
Server/makefile Normal file
View File

@@ -0,0 +1,35 @@
TARGET_EXEC ?= a.out
BUILD_DIR ?= ./build
SRC_DIRS ?= ./src
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c -or -name *.s)
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
DEPS := $(OBJS:.o=.d)
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
JSON_C_DIR=/path/to/json_c/install
CFLAGS += -I$(JSON_C_DIR)/include/json-c
# Or to use lines like: #include <json-c/json_object.h>
#CFLAGS += -I$(JSON_C_DIR)/include
LDFLAGS+= -L$(JSON_C_DIR)/lib -ljson-c
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
$(CC) $(OBJS) -o $@ $(LDFLAGS)
# c source
$(BUILD_DIR)/%.c.o: %.c
$(MKDIR_P) $(dir $@)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
$(RM) -r $(BUILD_DIR)
-include $(DEPS)
MKDIR_P ?= mkdir -p

126
Server/src/devicemgr.c Normal file
View File

@@ -0,0 +1,126 @@
#include "devicemgr.h"
/*
* This file provides an abstraction layer to access many devices
* simultaneously. by Dennis Gunia - 2025 - wwwm.dennisgunia.de
*/
enum SFDEVICE_STATE { NEW, OFFLINE, ONLINE, FAILED };
enum SFDEVICE_POWER { DISABLED, ENABLED, UNKNOWN };
struct SFDEVICE {
u_int16_t address;
int rs485_descriptor;
double reg_voltage;
u_int32_t reg_counter;
u_int8_t reg_status;
u_int8_t current_flap;
enum SFDEVICE_STATE deviceState;
enum SFDEVICE_POWER powerState;
};
#define SFDEVICE_MAXDEV 128
// next free slot to register device
int nextFreeSlot = -1;
struct SFDEVICE devices[SFDEVICE_MAXDEV];
void devicemgr_init() {
// reserve memory buffer
}
int devicemgr_readStatus(int device_id) {
double _voltage = 0;
u_int32_t _counter = 0;
u_int8_t _status =
sfbus_read_status(devices[device_id].rs485_descriptor,
devices[device_id].address, &_voltage, &_counter);
if (_status == 0xFF) {
devices[device_id].powerState = UNKNOWN;
devices[device_id].deviceState = OFFLINE;
return -1;
} else {
devices[device_id].reg_voltage = _voltage;
devices[device_id].reg_counter = _counter;
devices[device_id].reg_status = _status;
devices[device_id].powerState = ~((devices[device_id].reg_status >> 4)) & 0x01;
devices[device_id].deviceState = ONLINE;
if ((((devices[device_id].reg_status) >> 5) & 0x01) > 0){
devices[device_id].deviceState = FAILED;
}
return 0;
}
}
json_object * devicemgr_printDetails(int device_id){
// generate json object with status
json_object *root = json_object_new_object();
json_object_object_add(root, "id", json_object_new_int(device_id));
json_object_object_add(root, "address", json_object_new_int(devices[device_id].address));
json_object *status = json_object_new_object();
json_object_object_add(status, "voltage", json_object_new_double(devices[device_id].reg_voltage));
json_object_object_add(status, "rotations", json_object_new_int(devices[device_id].reg_counter));
json_object_object_add(status, "power", json_object_new_boolean(devices[device_id].powerState));
json_object_object_add(status, "raw", json_object_new_uint64(devices[device_id].reg_status));
switch(devices[device_id].deviceState){
case ONLINE:
json_object_object_add(status, "device", json_object_new_string("ONLINE"));
break;
case OFFLINE:
json_object_object_add(status, "device", json_object_new_string("OFFLINE"));
break;
case FAILED:
json_object_object_add(status, "device", json_object_new_string("FAILED"));
break;
case NEW:
json_object_object_add(status, "device", json_object_new_string("NEW"));
break;
}
json_object *status_flags = json_object_new_object();
json_object_object_add(status_flags, "errorTooBig", json_object_new_boolean(((devices[device_id].reg_status) >> 0) & 0x01));
json_object_object_add(status_flags, "noHome", json_object_new_boolean(((devices[device_id].reg_status) >> 1) & 0x01));
json_object_object_add(status_flags, "fuseBlown", json_object_new_boolean(((devices[device_id].reg_status) >> 2) & 0x01));
json_object_object_add(status_flags, "homeSense", json_object_new_boolean(((devices[device_id].reg_status) >> 3) & 0x01));
json_object_object_add(status_flags, "powerDown", json_object_new_boolean(((devices[device_id].reg_status) >> 4) & 0x01));
json_object_object_add(status_flags, "failSafe", json_object_new_boolean(((devices[device_id].reg_status) >> 5) & 0x01));
json_object_object_add(status_flags, "busy", json_object_new_boolean(((devices[device_id].reg_status) >> 6) & 0x01));
json_object_object_add(status, "flags", status_flags);
json_object_object_add(root, "status", status);
return root;
}
json_object * devicemgr_printDetailsAll(){
json_object *root = json_object_new_object();
json_object_object_add(root, "devices_all", json_object_new_int(nextFreeSlot + 1));
json_object *devices_arr = json_object_new_array();
int devices_online = 0;
for (int i = 0; i< (nextFreeSlot + 1); i++){
devicemgr_readStatus(i);
if ( devices[i].deviceState == ONLINE ){devices_online++;}
json_object_array_add(devices_arr, devicemgr_printDetails(i));
}
json_object_object_add(root, "devices", devices_arr);
json_object_object_add(root, "devices_online", json_object_new_int(devices_online));
printf("The json representation:\n\n%s\n\n", json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY));
return root;
}
int devicemgr_register(int rs485_descriptor, u_int16_t address) {
nextFreeSlot++;
devices[nextFreeSlot].address = address;
devices[nextFreeSlot].rs485_descriptor = rs485_descriptor;
devices[nextFreeSlot].reg_voltage = 0;
devices[nextFreeSlot].reg_counter = 0;
devices[nextFreeSlot].reg_status = 0;
devices[nextFreeSlot].current_flap = 0;
devices[nextFreeSlot].deviceState = NEW;
devices[nextFreeSlot].powerState = DISABLED;
// try to reach device
devicemgr_readStatus(nextFreeSlot);
return nextFreeSlot;
}

18
Server/src/devicemgr.h Normal file
View File

@@ -0,0 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <string.h>
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include <sys/types.h>
#include "sfbus.h"
#include <json-c/json_object.h>
#include <sys/types.h>
#include <json-c/json.h>
int devicemgr_readStatus(int device_id) ;
json_object * devicemgr_printDetails(int device_id);
json_object * devicemgr_printDetailsAll();
int devicemgr_register(int rs485_descriptor, u_int16_t address);

162
Server/src/main.c Normal file
View File

@@ -0,0 +1,162 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <sys/types.h>
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include "rs485.h"
#include "sfbus.h"
#include <unistd.h>
#include "devicemgr.h"
void printUsage(char *argv[]) {
fprintf(stderr, "Usage: %s -p <tty> -c <command> [value]\n", argv[0]);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
int opt;
u_int16_t addr_int = 0;
char *port = malloc(256);
char *command = malloc(16);
char *addr = malloc(16);
char *data = malloc(256);
command = "";
addr = "";
data = "";
while ((opt = getopt(argc, argv, "p:c:a:d:")) != -1) {
switch (opt) {
case 'p':
port = optarg;
break;
case 'c':
command = optarg;
break;
case 'a':
addr = optarg;
break;
case 'd':
data = optarg;
break;
default:
printUsage(argv);
}
}
if (access(port, F_OK) != 0) {
fprintf(stderr, "Filedescriptor: %s does not exist or cannot be opened\n",
port);
printUsage(argv);
}
// parse address
if (strlen(addr) == 0) {
fprintf(stderr, "Please specify address\n");
printUsage(argv);
} else {
addr_int = strtol(addr, NULL, 10);
}
// start program
setvbuf(stdout, NULL, _IONBF, 0); // do not buffer stdout!!!!
printf("Open device at %s\n", port);
int fd = rs485_init(port, B19200); // setup rs485
// test
devicemgr_register(fd,0);
devicemgr_register(fd,1);
devicemgr_printDetailsAll();
exit(1);
if (strcmp(command, "ping") == 0) {
sfbus_ping(fd, addr_int);
exit(0);
} else if (strcmp(command, "r_eeprom") == 0) {
char *buffer = malloc(64);
sfbus_read_eeprom(fd, addr_int, buffer);
printf("Read data: 0x");
print_charHex(buffer, 5);
printf("\n");
free(buffer);
exit(0);
} else if (strcmp(command, "w_addr") == 0) {
int n_addr = strtol(data, NULL, 10);
if (n_addr < 1) {
printf("Please specify new address > 0 with -d\n");
exit(-1);
}
// read current eeprom status
char *buffer_w = malloc(64);
char *buffer_r = malloc(64);
if (sfbus_read_eeprom(fd, addr_int, buffer_w) < 0) {
fprintf(stderr, "Error reading eeprom\n");
exit(1);
}
// modify current addr
u_int16_t n_addr_16 = n_addr;
memcpy(buffer_w, &n_addr_16, 2);
if (sfbus_write_eeprom(fd, addr_int, buffer_w, buffer_r) < 0) {
fprintf(stderr, "Error writing eeprom\n");
exit(1);
}
exit(0);
} else if (strcmp(command, "status") == 0) {
double voltage = 0;
u_int32_t counter = 0;
u_int8_t status = sfbus_read_status(fd, addr_int, &voltage, &counter);
printf("=======================\n");
printf("Status register flags :\n");
printf(" 00 -> errorTooBig : %i\n", (status >> 0) & 0x01);
printf(" 01 -> noHome : %i\n", (status >> 1) & 0x01);
printf(" 02 -> fuseBlown : %i\n", (status >> 2) & 0x01);
printf(" 03 -> homeSense : %i\n", (status >> 3) & 0x01);
printf(" 04 -> powerDown : %i\n", (status >> 4) & 0x01);
printf(" 05 -> failSafe : %i\n", (status >> 5) & 0x01);
printf(" 06 -> busy : %i\n", (status >> 6) & 0x01);
printf("Driver-Voltage : %.2fV\n", voltage);
printf("Rotations : %i\n", counter);
exit(0);
} else if (strcmp(command, "display") == 0) {
int flap = strtol(data, NULL, 10);
// read current eeprom status
char *buffer_w = malloc(4);
sfbus_display(fd, addr_int, flap);
exit(0);
} else if (strcmp(command, "display_fr") == 0) {
int flap = strtol(data, NULL, 10);
// read current eeprom status
char *buffer_w = malloc(4);
sfbus_display_full(fd, addr_int, flap);
exit(0);
}else if (strcmp(command, "reset") == 0) {
sfbus_reset_device(fd, addr_int);
exit(0);
} else if (strcmp(command, "power_on") == 0) {
sfbus_motor_power(fd, addr_int,1);
exit(0);
} else if (strcmp(command, "power_off") == 0) {
sfbus_motor_power(fd, addr_int,0);
exit(0);
} else {
fprintf(stderr, "Invalid command specified!\n");
printUsage(argv);
}
char *buffer = malloc(256);
char *cmd = "\xF0";
sfbus_send_frame(fd, 0, strlen(cmd), cmd);
int len = sfbus_recv_frame_wait(fd, 0xFFFF, buffer);
// printf("TEST:%i %s\n", len, buffer);
free(buffer);
return 0;
}

69
Server/src/rs485.c Normal file
View File

@@ -0,0 +1,69 @@
#include "rs485.h"
/*
* Open RS485 Interface (FT232RL)
*/
int rs485_init(char *device, int baud) {
int rs485_fd = open(device, O_RDWR);
if (rs485_fd < 0) {
printf("Error %i from open: %s\n", errno, strerror(errno));
return -1;
}
// Flush all data
int result = tcflush(rs485_fd, TCIOFLUSH);
if (result) {
perror("tcflush failed"); // just a warning, not a fatal error
return -1;
}
// Set port config and baud
struct termios options;
result = tcgetattr(rs485_fd, &options);
if (result) {
perror("tcgetattr failed");
close(rs485_fd);
return -1;
}
// Turn off any options that might interfere with our ability to send and
// receive raw binary bytes.
options.c_iflag &= ~(INLCR | IGNCR | ICRNL | IXON | IXOFF);
options.c_oflag &= ~(ONLCR | OCRNL);
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
// Set up timeouts: Calls to read() will return as soon as there is
// at least one byte available or when 100 ms has passed.
options.c_cc[VTIME] = 1;
options.c_cc[VMIN] = 0;
cfsetospeed(&options, baud);
cfsetispeed(&options, baud);
result = tcsetattr(rs485_fd, TCSANOW, &options);
if (result) {
perror("tcsetattr failed");
close(rs485_fd);
return -1;
}
rs485_trdir(rs485_fd, 1);
return rs485_fd;
}
/*
* Set RS485 Direction (FT232RL - RTS PIN)
*/
int rs485_trdir(int rs485_fd, int level) {
int status;
if (ioctl(rs485_fd, TIOCMGET, &status) == -1) {
perror("setRTS(): TIOCMGET");
return 0;
}
if (level)
status |= TIOCM_DTR;
else
status &= ~TIOCM_DTR;
if (ioctl(rs485_fd, TIOCMSET, &status) == -1) {
perror("setRTS(): TIOCMSET");
return 0;
}
return 1;
}

15
Server/src/rs485.h Normal file
View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <string.h>
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include <sys/types.h>
#define RS485TX 0
#define RS485RX 1
int rs485_init(char *device, int baud);
int rs485_trdir(int rs485_fd, int level);

229
Server/src/sfbus.c Normal file
View File

@@ -0,0 +1,229 @@
#include "sfbus.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void print_charHex(char *buffer, int length) {
int _tlength = length;
while (_tlength > 0) {
printf("%02X", (*buffer & 0xFF));
buffer++;
_tlength--;
}
}
void print_bufferHexRx(char *buffer, int length, u_int16_t address) {
printf("Rx (0x%04X): 0x", address);
print_charHex(buffer, length);
printf(" | %i bytes received\n", length);
}
void print_bufferHexTx(char *buffer, int length, u_int16_t address) {
printf("Tx (0x%04X): 0x", address);
print_charHex(buffer, length);
printf(" | %i bytes sent\n", length);
}
ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer) {
ssize_t len = 0;
int retryCount = 2;
do {
len = sfbus_recv_frame(fd, address, buffer);
retryCount--;
if (retryCount == 0) {
fprintf(stderr, "Rx timeout\n");
return -1;
}
} while (len <= 0);
print_bufferHexRx(buffer, len - 3, address);
return len;
}
ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer) {
// wait for start byte
char byte = 0x00;
int retryCount = 3;
while (byte != '+') {
byte = 0x00;
read(fd, &byte, 1);
retryCount--;
if (retryCount == 0) {
return -1;
}
}
u_int8_t frm_version;
u_int8_t frm_addr_l;
u_int8_t frm_addr_h;
u_int8_t frm_length;
u_int8_t frm_eof;
read(fd, &frm_version, 1);
read(fd, &frm_length, 1);
read(fd, &frm_addr_l, 1);
read(fd, &frm_addr_h, 1);
u_int16_t dst_addr = frm_addr_l | (frm_addr_h << 8);
if (dst_addr != address) {
return 0;
}
u_int8_t frm_length_counter = frm_length - 3;
// read all bytes:
while (frm_length_counter > 0) {
read(fd, buffer, 1);
buffer++;
frm_length_counter--;
}
read(fd, &frm_eof, 1);
if (frm_eof == '$') {
return frm_length;
} else {
return -1;
}
}
void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length,
char *buffer) {
int frame_size_complete = length + 6;
char *frame = malloc(frame_size_complete);
char *frame_ptr = frame;
*frame = '+'; // startbyte
frame++;
*frame = 0; // protocol version
frame++;
*frame = length + 3; // length
frame++;
*frame = (address);
frame++;
*frame = ((address >> 8));
frame++;
while (length > 0) {
*frame = *buffer;
length--;
buffer++;
frame++;
}
*frame = '$'; // startbyte
rs485_trdir(fd, 0);
int result = write(fd, frame_ptr, frame_size_complete);
print_bufferHexTx(frame_ptr + 5, frame_size_complete - 6, address);
free(frame_ptr);
// tcdrain(fd);
usleep(470 * (frame_size_complete + 1));
rs485_trdir(fd, 1);
}
int sfbus_ping(int fd, u_int16_t address) {
char *cmd = "\xFE";
char *buffer = malloc(64);
sfbus_send_frame(fd, address, strlen(cmd), cmd);
int len = sfbus_recv_frame_wait(fd, 0xFFFF, buffer);
if (len == 4 && *buffer == (char)0xFF) {
printf("Ping okay!\n");
free(buffer);
return 0;
} else {
printf("Ping invalid response!\n");
free(buffer);
return 1;
}
}
int sfbus_read_eeprom(int fd, u_int16_t address, char *buffer) {
char *cmd = "\xF0";
char *_buffer = malloc(256);
sfbus_send_frame(fd, address, strlen(cmd), cmd);
int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
if (len != 9) {
printf("Invalid data!\n");
return -1;
}
if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) {
printf("Invalid data!\n");
return -1;
}
memcpy(buffer, _buffer + 1, len - 4);
free(_buffer);
// printf("Read valid data!\n");
return len;
}
int sfbus_write_eeprom(int fd, u_int16_t address, char *wbuffer,
char *rbuffer) {
char *cmd = malloc(5);
*cmd = (char)0xF1; // write eeprom command
memcpy(cmd + 1, wbuffer, 4);
sfbus_send_frame(fd, address, 5, cmd);
free(cmd);
// wait for readback
char *_buffer = malloc(256);
int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
if (len != 9) {
printf("Invalid data!\n");
return -1;
}
if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) {
printf("Invalid data!\n");
return -1;
}
memcpy(rbuffer, _buffer + 1, len - 4);
free(_buffer);
// printf("Read valid data!\n");
return len;
}
int sfbus_display(int fd, u_int16_t address, u_int8_t flap) {
char *cmd = malloc(5);
*cmd = (char)0x10; // write eeprom command
*(cmd + 1) = flap;
sfbus_send_frame(fd, address, 2, cmd);
free(cmd);
return 0;
}
int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap) {
char *cmd = malloc(5);
*cmd = (char)0x11; // write eeprom command
*(cmd + 1) = flap;
sfbus_send_frame(fd, address, 2, cmd);
free(cmd);
return 0;
}
u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage,
u_int32_t *counter) {
char *cmd = "\xF8";
char *_buffer = malloc(256);
sfbus_send_frame(fd, address, strlen(cmd), cmd);
int res = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
if (res < 0){
return 0xFF;
}
u_int16_t _voltage = *(_buffer + 2) & 0xFF | ((*(_buffer + 1) << 8) & 0xFF00);
u_int32_t _counter =
*(_buffer + 6) & 0xFF | (((*(_buffer + 3) & 0xFF) << 24)) |
(((*(_buffer + 4) & 0xFF) << 16)) | (((*(_buffer + 5) & 0xFF) << 8));
double __voltage = ((double)_voltage / 1024) * 55;
*voltage = __voltage;
*counter = (u_int32_t)_counter;
return *_buffer;
}
void sfbus_reset_device(int fd, u_int16_t address) {
char *cmd = "\x30";
sfbus_send_frame(fd, address, strlen(cmd), cmd);
}
void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state) {
char *cmd = "\x20";
if (state > 0) {
cmd = "\x21";
}
sfbus_send_frame(fd, address, 1, cmd);
}

14
Server/src/sfbus.h Normal file
View File

@@ -0,0 +1,14 @@
#include "rs485.h"
ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer);
ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer);
void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, char *buffer);
void print_charHex(char *buffer, int length);
int sfbus_ping(int fd, u_int16_t address);
int sfbus_read_eeprom(int fd, u_int16_t address, char* buffer);
int sfbus_write_eeprom(int fd, u_int16_t address, char* wbuffer, char *rbuffer);
int sfbus_display(int fd, u_int16_t address, u_int8_t flap);
int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap);
u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int32_t *counter);
void sfbus_reset_device(int fd, u_int16_t address);
void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state);

View File

@@ -0,0 +1,51 @@
# Source and include
BUILD_DIR=build
SRCS=$(wildcard src/*.c)
OBJS=$(SRCS:%.c=build/%.o)
INC=-I ./inc
# MCU configuration
# Set MCU type, clock frequency and programmer
MCU=atmega8
CLOCK_FREQ=16000000
PROG_STR=usbasp
# Compiler flags
CFLAGS=-std=c11 -Wall -Wextra -Werror -mmcu=$(MCU) -DF_CPU=$(CLOCK_FREQ)
OPT_FLAGS=-O3 -g -DDEBUG
# Compiler and utility tools
OBJCOPY=avr-objcopy
CC=avr-gcc
# Project configuration
PROJ_NAME=sflap_controller_fw
PROJ_BLD=$(BUILD_DIR)/$(PROJ_NAME)
# Rules
all: $(PROJ_BLD).elf
$(PROJ_BLD).elf: $(OBJS)
$(CC) -o $@ $^ $(INC) $(CFLAGS) $(OPT_FLAGS) $(MCU_FLAGS)
$(OBJCOPY) -j .text -j .data -O ihex $@ $(PROJ_BLD).hex
$(OBJCOPY) -j .text -j .data -O binary $@ $(PROJ_BLD).bin
build/%.o: %.c
mkdir -p build/src
$(CC) -c -o $@ $(INC) $(CFLAGS) $(OPT_FLAGS) $(MCU_FLAGS) $<
release: OPT_FLAGS=-O2 -DNDEBUG
release: $(PROJ_BLD).elf
flash:
avrdude -c $(PROG_STR) -p $(MCU) -U flash:w:$(PROJ_BLD).hex:i
flash-debug:
avrdude -c $(PROG_STR) -p $(MCU) -U flash:w:$(PROJ_BLD).elf:e
clean:
rm -rf build
.PHONY = clean, release, flash, flash-debug

View File

@@ -0,0 +1,162 @@
#include "mctrl.h"
#include "rcount.h"
#include "rs485.h"
#include <avr/io.h>
#include <avr/wdt.h>
#include <stdlib.h>
#include <util/delay.h>
/*
* PD0 -> BUS_RX
* PD1 -> BUS_TX
* PD2 -> BUS_DIR (0=RECV/1=SEND)
*
* PD3 -> SENSOR_IN
*
* PC0-3 -> MOTOR CTRL
*/
uint16_t address = 0x0000;
int16_t calib_offset = 0x0000;
void eeprom_write_c(uint16_t address, uint8_t data) {
// disable interrupt
cli();
while (EECR & (1 << EEWE))
; // wait until previous write is done
EEAR = address;
EEDR = data;
EECR |= (1 << EEMWE); // enable Master Write Enable
EECR |= (1 << EEWE); // write one
sei();
}
uint8_t eeprom_read_c(uint16_t address) {
while (EECR & (1 << EEWE))
; // wait until previous write is done
EEAR = address;
EECR |= (1 << EERE); // read one
return EEDR;
}
#define CONF_CONST_OKAY (uint8_t)0xAA
#define CONF_ADDR_OKAY 0x0004
#define CONF_ADDR_ADDR 0x0000
#define CONF_ADDR_OFFSET 0x0002
void initialSetup() {
wdt_disable();
if (eeprom_read_c(CONF_ADDR_OKAY) == CONF_CONST_OKAY) {
uint8_t addrL = eeprom_read_c(CONF_ADDR_ADDR);
uint8_t addrH = eeprom_read_c(CONF_ADDR_ADDR + 1);
address = addrL | (addrH << 8);
uint8_t offsetL = eeprom_read_c(CONF_ADDR_OFFSET);
uint8_t offsetH = eeprom_read_c(CONF_ADDR_OFFSET + 1);
calib_offset = offsetL | (offsetH << 8);
} else {
eeprom_write_c(CONF_ADDR_ADDR, (uint8_t)0x00);
eeprom_write_c(CONF_ADDR_ADDR + 1, (uint8_t)0x00);
eeprom_write_c(CONF_ADDR_OFFSET, (uint8_t)0x00);
eeprom_write_c(CONF_ADDR_OFFSET + 1, (uint8_t)0x00);
eeprom_write_c(CONF_ADDR_OKAY, CONF_CONST_OKAY);
}
}
void readCommand() {
char *payload = malloc(64);
uint8_t payload_len = sfbus_recv_frame(address, payload);
if (payload_len > 0) {
// read command byte
uint8_t opcode = *payload;
// parse commands
if (opcode == (uint8_t)0x10) {
// 0x1O = Set Digit
uint8_t targetDigit = *(payload + 1);
mctrl_set(targetDigit, 0);
} else if (opcode == (uint8_t)0x11) {
// 0x11 = Set Digit (full rotation)
uint8_t targetDigit = *(payload + 1);
mctrl_set(targetDigit, 1);
} else if (opcode == (uint8_t)0xF0) {
// 0xFO = READ EEPROM
uint8_t bytes = 5;
char *msg = malloc(bytes + 1);
*msg = 0xAA;
for (uint16_t i = 1; i < (uint16_t)bytes + 1; i++) {
*(msg + i) = eeprom_read_c(i - 1);
}
_delay_ms(2);
sfbus_send_frame(0xFFFF, msg, bytes + 1);
free(msg);
} else if (opcode == (uint8_t)0xF1) {
// 0xF1 = WRITE EEPROM
eeprom_write_c(CONF_ADDR_OKAY, (char)0xFF);
for (uint16_t i = 0; i < 4; i++) {
eeprom_write_c(i, *(payload + 1 + i));
}
eeprom_write_c(CONF_ADDR_OKAY, CONF_CONST_OKAY);
// respond with readout
uint8_t bytes = 5;
char *msg = malloc(bytes + 1);
*msg = 0xAA;
for (uint16_t i = 1; i < (uint16_t)bytes + 1; i++) {
*(msg + i) = eeprom_read_c(i - 1);
}
_delay_ms(2);
sfbus_send_frame(0xFFFF, msg, bytes + 1);
free(msg);
// now use new addr
uint8_t addrL = eeprom_read_c(CONF_ADDR_ADDR);
uint8_t addrH = eeprom_read_c(CONF_ADDR_ADDR + 1);
address = addrL | (addrH << 8);
} else if (opcode == (uint8_t)0xF8) {
// 0xF8 = Get Status
char *msg = malloc(7);
*msg = getSts();
uint16_t voltage = getVoltage();
*(msg + 2) = (voltage >> 0) & 0xFF;
*(msg + 1) = (voltage >> 8) & 0xFF;
uint32_t counter = rc_getCounter();
*(msg + 6) = (counter >> 0) & 0xFF;
*(msg + 5) = (counter >> 8) & 0xFF;
*(msg + 4) = (counter >> 16) & 0xFF;
*(msg + 3) = (counter >> 24) & 0xFF;
_delay_ms(2);
sfbus_send_frame(0xFFFF, msg, 7);
free(msg);
} else if (opcode == (uint8_t)0xFE) {
// 0xFE = PING
char msg = 0xFF;
_delay_ms(2);
sfbus_send_frame(0xFFFF, &msg, 1);
} else if ((opcode & (uint8_t)0xFE) == (uint8_t)0x20) {
// 0x20 = poweroff; 0x21 is poweron
uint8_t state = opcode & (uint8_t)0x01;
mctrl_power(state);
} else if (opcode == (uint8_t)0x30) {
// 0x30 = reset
do {
wdt_enable(WDTO_15MS);
for (;;) {
}
} while (0);
} else {
// invalid opcode
char msg = 0xEE;
_delay_ms(2);
sfbus_send_frame(0xFFFF, &msg, 1);
}
}
free(payload);
}
int main() {
initialSetup();
rs485_init();
mctrl_init();
while (1 == 1) {
readCommand();
}
}

View File

@@ -0,0 +1,242 @@
#include "mctrl.h"
// Motor driver steps definition. Reverse for direction change.
uint8_t motor_steps[4] = {
0b00000001,
0b00000010,
0b00000100,
0b00001000,
};
uint8_t step_index = 0; // cuurent index in motor_steps
uint8_t target_flap = 0; // target flap
uint16_t absolute_pos = 0; // absolute position in steps
uint16_t rel_offset = 1400; // offset of '0' flap relative to home
uint16_t steps_since_home = 0; // steps since last home signal
// homing util variables
uint8_t homing = 0; // current homing step
uint8_t lastSens = 0; // home sonsor signal from last tick
// counter for auto powersaving
uint8_t ticksSinceMove = 0;
// value to goto after the current target_flap is reached. 255 = NONE.
uint8_t afterRotation = 255;
int16_t *delta_err;
// error and status flags
uint8_t sts_flag_errorTooBig = 0; // last home signal too early or too late
uint8_t sts_flag_noHome = 0; // no home signal detected. Wheel stuck
uint8_t sts_flag_fuse = 0; // blown fuse detcted
uint8_t sts_flag_pwrdwn = 0; // device is powered down by controller
uint8_t sts_flag_failsafe = 0; // device is powered down for safety reasons
uint8_t sts_flag_busy = 0; // device is busy
// voltage monitoring variables
uint16_t currentVoltage = 0; // current ADC reading
uint8_t currentFaultReadings = 0; // ticks with faulty readings (too many will
// trip pwrdwn and sts_flag_fuse)
// initialize motor controller
void mctrl_init() {
DDRC = 0x0F; // set all pins as outputs
PORTC = 0x00; // set all to LOW
DDRD &= ~(1 << PD3); // PD3 is input
PORTD |= (1 << PD3); // PD3 pullup
// setup adc
ADMUX = 0x07; // Aref, ADC7
ADCSRA =
(1 << ADEN) | (1 << ADSC) | (1 << ADPS1); // Enable ADC, Start first
// reading No frerunning, 8MHz
while ((ADCSRA & (1 << ADSC)) > 0)
; // wait until first reading is complete,
// to avoid error flag on first tick!
// setup timer for ISR
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC und Prescaler 64
OCR1A = 480; // 8.000.000 / 64 / 1000 für 1ms
OCR1A = 580; // 8.000.000 / 64 / 1000 für 1ms
// OCR1A = 450; // 8.000.000 / 64 /
// 1000 für 1ms
TIMSK = 1 << OCIE1A; // Timerinterrupts aktivieren
homing = 1;
delta_err = malloc(ERROR_DATASETS * sizeof(uint16_t));
_delay_ms(1000);
sei();
}
// call when critical fail. Powers down motor and sets flags
void failSafe() {
sts_flag_failsafe = 1;
PORTC = 0x00;
}
// read voltage non blocking (called every tick)
void readVoltage() {
currentVoltage = ADC; // read last measurement
ADMUX = 0x07; // select ADC7
ADCSRA |= (1 << ADSC); // trigger next reading
if (currentVoltage < 128) { // if voltage is too low, fuse is probably broken
currentFaultReadings++;
if (currentFaultReadings > 20) { // too many fault readings trigger failSafe
sts_flag_fuse = 1;
failSafe();
}
}
}
// MAIN service routine. Called by timer 1
ISR(TIMER1_COMPA_vect) {
readVoltage(); // read and check voltage
if (sts_flag_pwrdwn == 1 || sts_flag_failsafe == 1) {
return;
} // if sts_flag_pwrdwn, STOP!
if (steps_since_home >
STEPS_PRE_REV * 1.5) { // check if home is missing for too long
// home missing error. Wheel probably stuck or power fail
sts_flag_noHome = 1;
failSafe();
} else if (homing == 1) { // Homing procedure 1. step: move out of home
if ((PIND & (1 << PD3)) > 0) {
homing = 2;
} else {
mctrl_step();
}
} else if (homing == 2) { // Homing procedure 2. step: find magnet
mctrl_step();
if ((PIND & (1 << PD3)) == 0) {
homing = 3;
steps_since_home = 0;
absolute_pos = rel_offset;
incrementCounter();
}
} else if (homing == 3) { // Homing procedure 3. step: find magnet
if (absolute_pos <= 0) {
homing = 0;
absolute_pos = rel_offset;
}
mctrl_step();
absolute_pos--;
} else { // when no failsafe is triggered and homing is done
// calculate target position
uint16_t target_pos = (target_flap * STEPS_PRE_FLAP) + rel_offset;
if (target_pos >= STEPS_PRE_REV) {
target_pos -= STEPS_PRE_REV;
}
if (absolute_pos != target_pos) {
// if target position is not reached, move motor
ticksSinceMove = 0;
mctrl_step();
absolute_pos++;
if (absolute_pos >= STEPS_PRE_REV) {
absolute_pos -= STEPS_PRE_REV;
}
// detect home position
if ((PIND & (1 << PD3)) == 0) {
if (lastSens == 0) {
// new home transition
int16_t errorDelta =
(absolute_pos > (STEPS_PRE_REV / 2) ? absolute_pos - STEPS_PRE_REV
: absolute_pos);
sts_flag_errorTooBig =
(errorDelta > 30) || (errorDelta < -30) ? 1 : 0;
// storeErr(errorDelta);
absolute_pos = 0;
steps_since_home = 0;
// increment rotations counter
incrementCounter();
}
lastSens = 1;
} else {
lastSens = 0;
}
} else { // if target position is reached
if (afterRotation < 55) { // if after rotation is set, apply it as new target
target_flap = afterRotation;
afterRotation = 255;
} else if (ticksSinceMove < 2) { // if motor has not been moved
sts_flag_busy = 0;
} else if (ticksSinceMove < 50) { // if motor has not been moved
ticksSinceMove++;
} else { // power off after 50 ticks
// PORTC = 0x00; // turn off stepper
}
}
}
rc_tick(); // process counter tick, non-blocking
}
// TODO
void storeErr(int16_t error) {
int16_t *delta_err_tmp = malloc(ERROR_DATASETS * sizeof(uint16_t));
memcpy(delta_err, delta_err_tmp + sizeof(uint16_t),
((ERROR_DATASETS - 2) * sizeof(uint16_t)));
memcpy(&error, delta_err_tmp, sizeof(uint16_t));
free(delta_err);
delta_err = delta_err_tmp;
}
// TODO
void getErr(int16_t *error) {
memcpy(delta_err, error, (ERROR_DATASETS * sizeof(uint16_t)));
}
// return status flag
uint8_t getSts() {
uint8_t status = sts_flag_errorTooBig; // bit 0: delta too big
status |= sts_flag_noHome << 1; // bit 1: no home found
status |= sts_flag_fuse << 2; // bit 2: fuse blown
status |= sts_flag_pwrdwn << 4; // bit 4: device powered down
status |= sts_flag_failsafe << 5; // bit 5: failsafe active
status |= sts_flag_busy << 6; // bit 6: failsafe active
if ((PIND & (1 << PD3)) == 0) {
status |= (1 << 3);
}
return status;
}
// return voltage
uint16_t getVoltage() { return currentVoltage; }
// set target flap
void mctrl_set(uint8_t flap, uint8_t fullRotation) {
sts_flag_busy = 1;
if (fullRotation == 0) {
target_flap = flap;
// if (absolute_pos < STEPS_ADJ) {
// absolute_pos += STEPS_PRE_REV;
// }
// absolute_pos -= STEPS_ADJ;
} else {
target_flap = (target_flap + (STEPS_PRE_FLAP - 1)) % STEPS_PRE_FLAP;
afterRotation = flap;
}
}
// trigger home procedure
void mctrl_home() { homing = 1; }
// trigger home procedure
void mctrl_power(uint8_t state) {
if (state == 0) {
sts_flag_pwrdwn = 1;
PORTC = 0x00;
}else{
sts_flag_pwrdwn = 0;
PORTC = motor_steps[step_index];
}
}
// do stepper step (I/O)
void mctrl_step() {
step_index++;
steps_since_home++;
if (step_index > 3) {
step_index = 0;
}
PORTC = motor_steps[step_index];
}

View File

@@ -0,0 +1,36 @@
#pragma once
#define MP_A PC0
#define MP_B PC1
#define MP_C PC2
#define MP_D PC3
#define STEPS_PRE_REV 2025
#define STEPS_PRE_FLAP 45
#define STEPS_ADJ 0 // added per flap to compensate for motor power down
#define AMOUNTFLAPS 45
#define ERROR_DATASETS 8
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "rcount.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void mctrl_init();
void mctrl_step();
void mctrl_set(uint8_t flap, uint8_t fullRotation);
void getErr(int16_t* error);
uint8_t getSts();
uint16_t getVoltage();
void mctrl_power(uint8_t state);
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -0,0 +1,45 @@
#include "rcount.h"
uint8_t rc_eeprom_write_c(uint16_t address, uint8_t data) {
// disable interrupt
if (EECR & (1 << EEWE)) { return 1; }
EEAR = address;
EEDR = data;
EECR |= (1 << EEMWE); // enable Master Write Enable
EECR |= (1 << EEWE); // write one
return 0;
}
uint8_t rc_eeprom_read_c(uint16_t address) {
while (EECR & (1 << EEWE))
; // wait until previous write is done
EEAR = address;
EECR |= (1 << EERE); // read one
return EEDR;
}
uint32_t counter = (uint32_t)0xFFFFFFFF;
uint8_t counter_phase = 5;
void rc_tick() {
if (counter == (uint32_t)0xFFFFFFFF) { counter = rc_getCounter(); }
if (counter_phase < 5) {
cli();
if (rc_eeprom_write_c(0x100 + counter_phase, ((counter >> (counter_phase * 8)) & 0xFF)) == 0) {
counter_phase++;
}
sei();
}
}
void incrementCounter() {
counter++;
counter_phase = 0;
}
uint32_t rc_getCounter() {
uint32_t counter = rc_eeprom_read_c(0x100);
counter |= ((uint32_t)rc_eeprom_read_c(0x101) << 8);
counter |= ((uint32_t)rc_eeprom_read_c(0x102) << 16);
counter |= ((uint32_t)rc_eeprom_read_c(0x103) << 24);
return counter;
}

View File

@@ -0,0 +1,13 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void incrementCounter();
uint32_t rc_getCounter();
void rc_tick();
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -0,0 +1,86 @@
#include "rs485.h"
void rs485_init() {
// init I/O
DDRD &= ~(1 << PD0); // BUS_DIR & TX is OUTPUT
DDRD |= (1 << PD2) | (1 << PD1); // BUS_DIR & TX is OUTPUT
PORTD &= 0x07; // clear PD0-PD4
// init UART
UBRRH = (BAUDRATE >> 8);
UBRRL = BAUDRATE; // set baud rate
UCSRB |= (1 << TXEN) | (1 << RXEN); // enable receiver and transmitter
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // 8bit data format
}
void dbg(char data) {
while (!(UCSRA & (1 << UDRE)))
;
UDR = data;
}
void rs485_send_c(char data) {
PORTD |= (1 << PD2); // set transciever to transmitt
while (!(UCSRA & (1 << UDRE)))
; // wait until buffer is empty
UCSRA = (1 << TXC); // clear transmit Complete bit
UDR = data;
while (!(UCSRA & (1 << TXC)))
; // wait until transmitt complete
PORTD &= ~(1 << PD2); // set transciever to transmitt
}
void rs485_send_str(char* data) {
for (unsigned int i = 0; i < sizeof(data); i++) {
rs485_send_c(data[i]);
}
}
char rs485_recv_c() {
while (!(UCSRA & (1 << RXC)))
;
; // wait while data is being received
return UDR;
}
// SFBUS Functions
uint8_t sfbus_recv_frame(uint16_t address, char* payload) {
while (rs485_recv_c() != '+') {} // Wwait for start byte
uint8_t frm_version = rs485_recv_c();
if (frm_version != 0) return 0;
uint8_t frm_length = rs485_recv_c();
uint8_t frm_addrL = rs485_recv_c();
uint8_t frm_addrH = rs485_recv_c();
uint16_t frm_addr = frm_addrL | (frm_addrH << 8);
if (frm_addr != address) return 0;
char* _payload = payload;
for (uint8_t i = 0; i < (frm_length - 3); i++) {
*_payload = rs485_recv_c();
_payload++;
}
if (rs485_recv_c() != '$') return -1;
return frm_length;
}
void sfbus_send_frame(uint16_t address, char* payload, uint8_t length) {
char framelen = length;
rs485_send_c(SFBUS_SOF_BYTE); // send startbyte 3 times
rs485_send_c(0); // send protocol version
rs485_send_c(framelen + 3); // send lentgh of remaining frame
rs485_send_c(address & 0xFF); // target address
rs485_send_c((address >> 8) & 0xFF);
while (framelen > 0) { // send payload
rs485_send_c(*payload);
payload++;
framelen--;
}
rs485_send_c(SFBUS_EOF_BYTE); // send end of frame byte
}

View File

@@ -0,0 +1,27 @@
#pragma once
//#define F_CPU 16000000UL
#define UART_BAUD 19200
#define BAUDRATE ((F_CPU) / (UART_BAUD * 16UL) - 1) // set baud rate value for UBRR
#define SFBUS_SOF_BYTE '+'
#define SFBUS_EOF_BYTE '$'
#include <avr/io.h>
#include <avr/interrupt.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void dbg(char data);
void rs485_init(void);
void rs485_send_c(char data);
void rs485_send_str(char* data);
char rs485_recv_c(void);
uint8_t sfbus_recv_frame(uint16_t address, char* payload);
void sfbus_send_frame(uint16_t address, char* payload, uint8_t length);
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -0,0 +1,153 @@
#include <Stepper.h>
#define BAUDRATE 115200
#define STEPPERPIN1 11
#define STEPPERPIN2 10
#define STEPPERPIN3 9
#define STEPPERPIN4 8
#define STEPS 2038 //28BYJ-48 stepper, number of steps
#define HALLPIN 7 //Pin of hall sensor
#define AMOUNTFLAPS 45
#define ROTATIONDIRECTION 1 //-1 for reverse direction
#define OVERHEATINGTIMEOUT 2 //timeout in seconds to avoid overheating of stepper. After starting rotation, the counter will start. Stepper won't move again until timeout is passed
unsigned long lastRotation = 0;
//globals
int displayedLetter = 0; //currently shown letter
int desiredLetter = 0; //letter to be shown
const String letters[] = {" ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Ä", "Ö", "Ü", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ".", "-", "?", "!"};
Stepper stepper(STEPS, STEPPERPIN1, STEPPERPIN3, STEPPERPIN2, STEPPERPIN4); //stepper setup
bool lastInd1 = false; //store last status of phase
bool lastInd2 = false; //store last status of phase
bool lastInd3 = false; //store last status of phase
bool lastInd4 = false; //store last status of phase
float missedSteps = 0; //cummulate steps <1, to compensate via additional step when reaching >1
int currentlyrotating = 0; // 1 = drum is currently rotating, 0 = drum is standing still
int stepperSpeed = 10; //current speed of stepper, value only for first homing
int eeAddress = 0; //EEPROM address for calibration offset
int calOffset; //Offset for calibration in steps, stored in EEPROM, gets read in setup
int receivedNumber = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(BAUDRATE);
Serial.println("starting unit");
stepperSpeed = 17; //until homing is implemented
}
void loop() {
// put your main code here, to run repeatedly:
int calLetters[10] = {0, 26, 1, 21, 14, 43, 30, 31, 32, 39};
for (int i = 0; i < 10; i++) {
int currentCalLetter = calLetters[i];
rotateToLetter(currentCalLetter);
delay(5000);
}
}
//rotate to letter
void rotateToLetter(int toLetter) {
if (lastRotation == 0 || (millis() - lastRotation > OVERHEATINGTIMEOUT * 1000)) {
lastRotation = millis();
//get letter position
int posLetter = -1;
posLetter = toLetter;
int posCurrentLetter = -1;
posCurrentLetter = displayedLetter;
//int amountLetters = sizeof(letters) / sizeof(String);
#ifdef serial
Serial.print("go to letter: ");
Serial.println(letters[toLetter]);
#endif
//go to letter, but only if available (>-1)
if (posLetter > -1) { //check if letter exists
//check if letter is on higher index, then no full rotaion is needed
if (posLetter >= posCurrentLetter) {
#ifdef serial
Serial.println("direct");
#endif
//go directly to next letter, get steps from current letter to target letter
int diffPosition = posLetter - posCurrentLetter;
startMotor();
stepper.setSpeed(stepperSpeed);
//doing the rotation letterwise
for (int i = 0; i < diffPosition; i++) {
float preciseStep = (float)STEPS / (float)AMOUNTFLAPS;
int roundedStep = (int)preciseStep;
missedSteps = missedSteps + ((float)preciseStep - (float)roundedStep);
if (missedSteps > 1) {
roundedStep = roundedStep + 1;
missedSteps--;
}
stepper.step(ROTATIONDIRECTION * roundedStep);
}
}
else {
//full rotation is needed, good time for a calibration
#ifdef serial
Serial.println("full rotation incl. calibration");
#endif
//calibrate(false); //calibrate revolver and do not stop motor
//startMotor();
stepper.setSpeed(stepperSpeed);
for (int i = 0; i < posLetter; i++) {
float preciseStep = (float)STEPS / (float)AMOUNTFLAPS;
int roundedStep = (int)preciseStep;
missedSteps = missedSteps + (float)preciseStep - (float)roundedStep;
if (missedSteps > 1) {
roundedStep = roundedStep + 1;
missedSteps--;
}
stepper.step(ROTATIONDIRECTION * roundedStep);
}
}
//store new position
displayedLetter = toLetter;
//rotation is done, stop the motor
delay(100); //important to stop rotation before shutting of the motor to avoid rotation after switching off current
stopMotor();
}
else {
#ifdef serial
Serial.println("letter unknown, go to space");
#endif
desiredLetter = 0;
}
}
}
//switching off the motor driver
void stopMotor() {
lastInd1 = digitalRead(STEPPERPIN1);
lastInd2 = digitalRead(STEPPERPIN2);
lastInd3 = digitalRead(STEPPERPIN3);
lastInd4 = digitalRead(STEPPERPIN4);
digitalWrite(STEPPERPIN1, LOW);
digitalWrite(STEPPERPIN2, LOW);
digitalWrite(STEPPERPIN3, LOW);
digitalWrite(STEPPERPIN4, LOW);
#ifdef serial
Serial.println("Motor Stop");
#endif
currentlyrotating = 0; //set active state to not active
delay(100);
}
void startMotor() {
#ifdef serial
Serial.println("Motor Start");
#endif
currentlyrotating = 1; //set active state to active
digitalWrite(STEPPERPIN1, lastInd1);
digitalWrite(STEPPERPIN2, lastInd2);
digitalWrite(STEPPERPIN3, lastInd3);
digitalWrite(STEPPERPIN4, lastInd4);
}