Skip to the content
PCBKitNew board
4 layers229 × 157 mmOMower, the printed circuit board in 3D

SDK for open-source open-hardware 2/4 wheels robots platform

Size
229 × 157 mm
Copper layers
4
Thickness
1.6 mm
Parts
421
Nets
338
Pads
1,449
Tracks, vias
4,619, 537
Pours
28
Routed
Yes
KiCad
KiCad 4
Created
6 Jan 2018
Updated
12 Apr 2019

Overview

OMower is an open-source printed circuit board by vasimv, from the vasimv/OMower repository on GitHub, published under the GPL-3.0 licence. It is a 4-layer board of 229 × 157 mm with 421 parts on 338 nets, routed with 4,619 tracks and 537 vias.

It is built around the ATSAM3X8EA-AU, ACS725LLCTR-30AB-T and TS30042-M050QFNR, with the L78L12ACU, PCA9512ADP and PMEG6010ER among its other parts. Its parts include 119 resistors, 110 capacitors, 36 diodes, 21 connectors and 10 ICs. It belongs with the robots and motor control boards and the SAM D and SAM boards of this library.

Main components

10

README

README.md

OMower project is open-source open-hardware wheeled robots platform with 32-bit ARM ATSAM3X8E microcontroller, same as in Arduino Due. The project compiles under Arduino IDE (requires patching standard ATSAM platform library files to support all GPIO lines of the MCU).

The project was inspired by ardumower project (https://github.com/Ardumower/ardumower) and uses few bits of its code.

FEATURES

Control, measurements and navigation routines for wheeled robots (primarily lawn mowers but not limited to) with wire perimeters, sonars and other sensors, GPS or RTK GPS (centimeters-level precision).

Support for 2 (with third support wheel) or 4 motors platforms. Brushed motors supported with Polulu Dual MC33926 (onboard) or IHM12A1 controllers (external), brushless motors will require external ESCs (controlled by PPM/servo output).

Includes PPM/servo output for the brushless mowing motor (or you may use onboard for brushed mowing motor) and step-motor drivers for cutter's height adjusting.

Supports many communication ports of ATSAM3X8E with onboard connectors to connect almost everything.

It may operate with pure pfodApp (or Modbus) user interface but has limited support for Robot OS (ROS).

HARDWARE

The board is based on ATSAM3X8E-AU MCU in 144-pins LQFP case (for arduino IDE it looks like Arduino Due without "programming" port).

Power subsystem includes step-down charging regulator (up to 4A charging current) and step-up for solar battery, bi-stable relay for emergency shutdown. Has 3 switching regulators to provide 3.3V and 5V to multiple internal and external devices, precise linear regulator for analog parts.

Supports battery voltages up to 28 volts, has onboard switching regulators for external charger and solar panel.

Three ACS725-30 current hall sensors to measure consumption and charging currents up to 30A real-time.

Multiple connectors for everything mower or any other robot needed with 5V->3.3V logic conversion (6x HC-SR04 sonars, 5 odometers, 3 serial ports, 4 wire perimeter sensors, two bumper sensors, lawns and drops sensors, two temperature NTC termistors connectors, two SPI ports, LEDs, button and more).

Has I2C buffers (both 3.3V and 5V versions) to connect multiple I2C devices, USB port (firmware upload), external 12-channel ADC MAX11617 (connected to I2C).

Has port for Orange PI Zero (for RTK GPS and Wifi connectivity, firmware upload), can be replaced by any Wifi/Bluetooth adapter connected to serial port of MCU.

Multiple PPM/servo outputs for external stuff with standard 3-pins connectors.

Note, board requires external components: external IMU GY-80 board or MPU-9250 board, external motors controllers and steppig motor driver boards. External charger voltage must be 6 volts higher than maximum battery voltage (i.e. for 14.6V LiFePo-battery it must provide 20..34V).

Latest version is 3, in v4 version the board will include FRAM chip to store settings/waypoints/etc (as ATSAM3X8E's flash is getting erased when uploading new firmware) and onboard IMU MPU9250.

Schematics and KiCad development files for the 4-layers board is in hardware folder. Version 3 board variant can be ordered from oshpark: https://oshpark.com/shared_projects/ILEdXK2T

SOFTWARE

The SDK's main goal is isolate hardware stuff from higher level software and easy development of wheeled robot platforms. It configures timers, interrupts, ADCs and other stuff to provide API to develop software without underlying hardware knowledge. It provides basic control and navigation stuff (like moving between points with RTK GPS), external ports (like sonars or PPM/servo stuff), measurements for ADCs (internal and onboard MAX11617), etc.

Look omower-*.h header files for API classes, check OMower_Simple firmware to see how to use them.

OMower SDK includes patches (see .patch files) for standard ATSAM libraries to support all GPIO's of ATSAM3X8E (compatible GPIO mapping with Taijuino Due Pro). Without them you won't able to use all ports of the OMower board!

Some of OMower stuff is not compatible with other arduino libraries, check restrictions.txt file.

Decawave DWM1000 radiotags navigation support is not tested yet, requires DWM1000 tags connected to MCU with MyRangeTag software, see https://github.com/vasimv/MyRangeTag

USAGE

Place OMower folder into ~/Arduino/libraries, choose your board in omower-defs.h (currently supported boards are OMower v3 and Arduino Due + IHM12A1 motor controller. Remember to patch ATSAM hardware library files to use all GPIOs of ATSAM3X8E MCU.

Clone https://github.com/vasimv/OMower_Simple and put its folder into ~/Arduino, compile and upload. Use pfodApp to control the robot.

ROS support

At this moment, ROS support is limited and includes sending some of sensors data to ROS (with *MultiArray messages but i planning to convert them to standartized message types), /cmd_vel support and routing debug and user interface to ROS topics. See OMower_Simple firmware example on how to enable ROS in your firmware.

HOW IT WORKS

OMower software must define all needed objects, set pointers to other objects where it needed (like gps object needs to set pointer to imu object), call all begin() functions of objects (hardware init, called just once), then sets values for objects parameters and call init() functions (software init, can be called many times to reset the object's hardware), define poll10/20/50 hooks functions to call objects poll*() functions from there (see OMower_Simple.ino for example).

One of most important classes is motors object (see omower-motors.h), it controls motor drivers from its poll10() function. User just calls functions roll/move (to simple turning or driving in a specific direction) or rollCourse/MoveCourse to drive with navigation by something (compass, gps, etc).

IMU stuff (compass, gyro, accelerometer) are read in imu object (omower-imu.h) by its poll50() function. It does filtering/calculation and provide angle values for compass and pitch/yaw/roll in degrees (see omower-imu.h). The imu object is daughter class of navThing class (see omower-root.h) that means it has readCourseError() function, so it can be used for navigation by motors object. Currently it supports navigation by compass angle.

GPS object is daughter class of navThing too, so it supports navigation. All coordinates are stored in int32_t values (so, 18.3495,-68.5960 will be 183495000,-685960000 actually) to improve precision (otherwise it would need large float class which does not exists in arduino framework). The user software must interface with a GPS receiver and feed NMEA lines from it to gps::parseString() function or raw coordinates to gps::settCoords() (see omower-gps.h). In precision mode (when centimeters-precise coordinates are used) - the gps object calculates robot's true coordinates using offset of GPS's antenna (distance from robot's center and angle).

Power object (omower-power.h) handles power stuff (battery, solar panel and charger regulators) and provides human-readable values of voltages and currents.

Mow object (omower-mow.h) manages the mowing motor(s) and its actuator (if have) to adjust cutting height. Note, currently it supports only PPM regulation on PWM-E output (brushless motors ESC connected to it), but will support brushed motors too (in 2 wheel motors + mow motor configuration).

Perimeter object (omower-perimeter.h) supports up to 4 wire perimeter sensors (same as for ardumower, just inductor+analog amplifier).

Serial object (omower-serial.h) handles communication with serial ports (as you can't use arduino's objects for that because possible interrupts conflicts). It has also better printf() functions which supports %f/%g for floats. UART (Serial.*) interface works with DMA (through built-in PDC) with huge output buffer (2048 bytes, can be changed in omower-debug.h), so debug output function won't cause slow-downs.

Sonars object (omower-sonars.h) handles HC-SR04 sonars (up to 6). It returns sonar's reported distance (in centimeters) through its readSonar() function. Since motors routines do not check for any obstacles during movement (except overcurrent on motors drivers), the user software must check sonars and bumpers to avoid obstacles and move around them.

At start of initialization chassis object (omower-chassis.h) initializes interrupts. This is most important task as almost all of OMower's stuff is done through interrupts hooks. It configures TIM7 to generate interrupts 100 times per second.

At every TIM7 interrupt, it reads 12 channels of MAX11617 ADC to "uint16_t adc11617Arr[]" (defined in max11617-adc-scan.h), this array is accessed from other OMower's objects (like power object, but of course you can read its values directly).

Every second cycle of TIM7 interrupt it calls user's poll50() hook, at every fifth - poll20() hook, at every tenth - poll10(). User's software must define these functions, set it through chassis::setHooksPoll() function and call all other objects poll10/20/50 functions from there. By default, to call hook functions it creates software interrupts for each kind of them (defined symbol USE_SOFTWARE_INTERRUPTS in omower-defs-omowerv3.h), so they are running asynchronous. Without USE_SOFTWARE_INTERRUPTS - poll50/20/10 hooks called after each other and you are limited to 20ms total time for all of them (OMower SDK functions were optimized to comply with that time and software interrupts can be turned off but if you place some other CPU hungry stuff in it - you will need software interrupts).

It was possible to create automatic binding for poll functions (so user wouldn't need to call all objects poll*() functions from firmware code), but it was decided not to do so to simplify the SDK internals.

All internal ADC channels of ATSAM3X8E are read by separate TIM5 interrupts 38461 times per second to the "adcArr[]" array (see due-adc-scan.h for its structure). This array is accessed by other omower objects from their poll10/20/50 functions, so no need to read it directly (but you still can do). Note, it is possible to add circle buffer to every channel read, so you won't miss any of value (this method is used in wire perimeter class for FFT filtering of the perimeter signal) through adcAddChannel() function (due-adc-scan.h).

PWM and TCC (in PWM mode) outputs are configured through pwmServo object (omower-pwmservo.h), don't use other methods to modify their output as it may conflict with OMower code. Since the code uses some MCU's timers, you won't able to use these for other things (Timer0, Timer6, Timer8 in pwmServo, Timer5 in due-adc-scan.cpp, Timer7 in chassis). Usually, nothing uses them but some of arduino libraries do (like Servo library, which you wouldn't need as there is pwmServo object).

Debug function debug() is defined in omower-debug.h. By default, it sends its output to Serial device, has ability to set priority for debug messages (so low-priority stuff won't be send at all).

There are some other objects which are easy to understand (omower-rtc.h for RTC clock, omower-current*.h for current sensors, omower-odometry.h for odometry sensors), please, look their header files and OMower_Simple firmware code if you want to know how they are used.

Parts

421
QtyValueFootprintReferences
230.1uFCapacitors_SMD:C_0603C21, C22, C23, C32, C33, C34, C35, C45, C46, C47, C52, C53, C55, C56, C57, C66 +7
221K5Resistors_SMD:R_0603R1, R12, R15, R18, R21, R25, R26, R27, R28, R29, R30, R31, R32, R33, R35, R119 +6
2010uFCapacitors_SMD:C_1206C36, C37, C48, C54, C58, C59, C61, C63, C65, C71, C82, C89, C105, C106, C108, C109 +4
180.1uFCapacitors_SMD:C_0805C11, C12, C13, C14, C15, C19, C20, C28, C29, C51, C83, C87, C101, C103, C104, C110 +2
1810KResistors_SMD:R_0603R23, R63, R65, R68, R79, R80, R84, R85, R86, R87, R88, R91, R92, R93, R117, R118 +2
182K2Resistors_SMD:R_0603R5, R11, R14, R17, R20, R34, R37, R38, R39, R40, R41, R42, R43, R44, R48, R49 +2
18CD0603-Z3Diodes_SMD:SOD-523D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, D32, D33 +2
175K1Resistors_SMD:R_0603R2, R47, R56, R66, R67, R77, R78, R106, R107, R108, R109, R110, R111, R112, R113, R116 +1
12100uFCapacitors_SMD:c_elec_6.3x5.7C1, C2, C3, C4, C5, C6, C64, C68, C73, C75, C79, C84
9620RResistors_SMD:R_0603R83, R90, R99, R100, R101, R102, R103, R104, R105
843KResistors_SMD:R_0603R51, R59, R61, R69, R73, R75, R96, R114
84K75Resistors_SMD:R_0603R52, R58, R60, R71, R72, R76, R97, R115
8620Resistors_SMD:R_0603R4, R7, R10, R13, R16, R19, R22, R62
710uFCapacitors_SMD:C_0603C18, C31, C49, C50, C74, C76, C77
7TVS 24VResistors_SMD:R_0402D4, D5, D6, D35, D36, D37, D38
610nFResistors_SMD:R_Array_Concave_4x0402CP1, CP2, CP3, CP4, CP5, CP6
647uFCapacitors_Tantalum_SMD:TantalC_SizeX_EIA-7343C26, C27, C62, C67, C78, C90
5PMEG6010Diodes_SMD:SOD-123D10, D11, D12, D14, D16
4470uFCapacitors_SMD:c_elec_8x10.5C42, C43, C80, C102
4680uFAC-Stuff:CPCASE-12.5C7, C8, C9, C10
4MH2029-300YResistors_SMD:R_0805FB1, FB2, FB3, FB4
3100pFCapacitors_SMD:C_0805C16, C17, C86
3100uFCapacitors_Tantalum_SMD:TantalC_SizeD_EIA-7343_ReflowC40, C81, C100
3150RResistors_SMD:R_Array_Convex_8x0602RP1, RP2, RP3
318pFCapacitors_SMD:C_0805C24, C25, C30
3220uFCapacitors_Tantalum_SMD:TantalC_SizeC_EIA-6032_ReflowC39, C60, C92
34.7uHChoke_SMD:Choke_SMD_Wuerth-WE-PD2-Typ-MSL1, L2, L6
3ACS725LLCTR-30AB-TSMD_Packages:SOIC-8-NU2, U3, U12
3SD2114S040S8R0Diodes_SMD:SMB_StandardD13, D15, D17
22MResistors_SMD:R_0603R3, R24
233uHAC-Stuff:Choke-PG1096L4, L5
239RResistors_SMD:R_0603R54, R55
2470RResistors_SMD:R_0805R45, R50
26RResistors_SMD:R_0805R70, R74
29pFCapacitors_SMD:C_0805C38, C41
2IRLB8748TO_SOT_Packages_THT:TO-220_Neutral123_Horizontal_LargePadsQ2, Q3
2JP-SLEWPin_Headers:Pin_Header_Straight_1x02JP2, JP3
2L78L12ATO_SOT_Packages_SMD:SOT89-3_HousingU9, U10
2PCA9512ADPHousings_SSOP:MSOP-8_3x3mm_Pitch0.65mmU13, U14
2TS30042-M050QFNRHousings_DFN_QFN:QFN-16-1EP_3x3mm_Pitch0.5mmU5, U15
2TVS 36VResistors_SMD:R_0402D8, D9
110A fuse PPTCVaristors:RV_Disc_D21.5_W5.3_P10F2
110nFCapacitors_SMD:C_0805C107
112MHzCrystals:crystal_FA238-TSX3225X1
1133RResistors_SMD:R_0805R46
115FAC-Stuff:Supercap-Vishay_E3_22_24C44
125RResistors_SMD:R_0603R64
132.768KHzResistors_SMD:R_1206Y1
147uHChoke_SMD:Choke_SMD_7.3x7.3_H3.5L3
150A fuseAC-Stuff:MAXI-Fuse-Clip-29.21F1
15Vsec-1Pin_Headers:Pin_Header_Straight_1x04P37
15Vsec-2Pin_Headers:Pin_Header_Straight_1x04P38
15Vsec-3Pin_Headers:Pin_Header_Straight_1x04P40
15Vsec-4Pin_Headers:Pin_Header_Straight_1x04P41
15Vsec-5Pin_Headers:Pin_Header_Straight_1x04P46
15Vsec-6Pin_Headers:Pin_Header_Straight_1x04P48
16K8Resistors_SMD:R_0603R53
1ACTIVITYLEDs:LED-3MMD7
1ADC-RSVPin_Headers:Pin_Header_Straight_1x03P64
1ATSAM3X8EA-AUHousings_QFP:LQFP-144_20x20mm_Pitch0.5mmU6
1BUMPER-1Pin_Headers:Pin_Header_Straight_1x04P11
1BUMPER-2Pin_Headers:Pin_Header_Straight_1x04P12
1BUTTONPin_Headers:Pin_Header_Straight_1x02P49
1Batt-ExtconnPin_Headers:Pin_Header_Straight_1x02P29
1BeeperPin_Headers:Pin_Header_Straight_1x02P34
1CANPin_Headers:Pin_Header_Straight_1x05P33
1Charge inConnectors_Molex:Molex_MiniFit-JR-5569-04A2_2x02x4.20mm_AngledP32
1DAC-1Pin_Headers:Pin_Header_Straight_1x04P42
1DAC-2Pin_Headers:Pin_Header_Straight_1x04P43
1DROP-1Pin_Headers:Pin_Header_Straight_1x04P14
1DROP-2Pin_Headers:Pin_Header_Straight_1x04P15
1DRV8825_1AC-Stuff:POLOLU-DRV8825X4
1DRV8825_2AC-Stuff:POLOLU-DRV8825X5
1Dual_MC33926_1AC-Stuff:POLULU-DUAL_MC33926X2
1Dual_MC33926_2AC-Stuff:POLULU-DUAL_MC33926X3
1E-OFF buttonPin_Headers:Pin_Header_Straight_1x02P8
1E-ON buttonPin_Headers:Pin_Header_Straight_1x02P10
1ERASEButtons_Switches_SMD:SW_SPST_EVQPE1SW1
1FANPin_Headers:Pin_Header_Straight_1x03P28
1FDV301NTO_SOT_Packages_SMD:SOT-23Q1

The 329 most common of 421 parts.

Questions

How big is the OMower PCB?

It measures 229 × 157 mm and has 4 copper layers, 1.6 mm thick.

What parts does the OMower use?

421 parts, built around the ATSAM3X8EA-AU, ACS725LLCTR-30AB-T, TS30042-M050QFNR and L78L12ACU. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the OMower KiCad files?

From the vasimv/OMower repository on GitHub, at the commit this page was made from: the board is hardware/OMower/omower.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.

Can I use the OMower design in my own project?

Its repository publishes it under the GPL-3.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 2 layers50 × 50 mmLazer amplitude modulation, the printed circuit board in 3D

    Lazer amplitude modulation

    manyetox/Light-Modulator-MEMS-Mic-Amp

    PCB designs for a Bluetooth audio-controlled laser/LED modulator and MEMS microphone receiver/amplifier for optical audio experiments.

    25 parts
  • 2 layersDuePi, the printed circuit board in 3D

    DuePi

    radioelf/Arduino-Due-mod-for-GPIO-compatible-Raspberry-Pi

    PCB arduino Due para DuePi y Gpio Raspberry Pi

    120 parts1
  • 2 layers47.6 × 90.2 mmRoben, the printed circuit board in 3D

    Roben

    akornsys-rdi/robgednaut

    Robust and easy-to-use introduction-to-robotics platform

    92 parts
  • 4 layers58.9 × 48.4 mmApppd, the printed circuit board in 3D

    Apppd

    chithigun23/ANUFS-APPPD

    An update to the Accelerator Pedal Position Plausibility Device to remain compliant with the use of a paddle shift system.

    103 parts
  • 4 layers166.3 × 70 mmGanglia, the printed circuit board in 3D

    Ganglia

    H2O-Tnp/ganglia

    Ganglia is an open BLDC / brushed motor driver platform — custom PCB hardware plus STM32 firmware that runs a real-time control loop on top of FreeRTOS.

    202 parts
  • 2 layers104.1 × 73.7 mm19V 10A Standalone, the printed circuit board in 3D

    19V 10A Standalone

    Kenkneeshio/SeniorDesign-Team9

    This is SDSU's Spring 2023 Senior Design A Team 9: Robot Power System GitHub

    35 parts