Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NanoDCMot

Firmware for Arduino Nano (ATmega328P) to control a dual L298N motor driver with optional quadrature encoders, using a framed protocol over I2C, SPI, or Serial.

Configuration

All configuration lives in include/config.h.

Bus selection

Select exactly one bus:

#define BUS_USE_I2C 1
#define BUS_USE_SPI 0
#define BUS_USE_SERIAL 0

Bus settings

#define I2C_SLAVE_ADDRESS 0x69
#define SPI_MODE_CONFIG 0
#define SPI_CLOCK_HZ 4000000UL
#define SERIAL_BAUD 115200UL

Notes:

  • I2C and Serial use the settings above directly.
  • SPI runs in slave mode; the master sets the clock. SPI_CLOCK_HZ is informational and used by the host configuration.

Protocol limits

#define PROTOCOL_SOF 0xAA
#define PROTOCOL_MAX_DATA 24

PROTOCOL_MAX_DATA limits the payload size inside a frame (opcode + payload). Increase only if needed.

Motor driver pins (defaults for Arduino Nano)

#define PIN_ENA 5
#define PIN_ENB 6
#define PIN_IN1 7
#define PIN_IN2 8
#define PIN_IN3 4
#define PIN_IN4 9

These map to the L298N pins: ENA/PWMA, ENB/PWMB, IN1-4.

Encoders

#define ENABLE_ENCODERS 0
#define ENC1_A_PIN 2
#define ENC1_B_PIN 3
#define ENC2_A_PIN A0
#define ENC2_B_PIN A1

Set ENABLE_ENCODERS to 1 to enable full quadrature decoding via pin-change interrupts.

Protocol

Frame format

All buses use the same framed protocol:

SOF | LEN | OPCODE | PAYLOAD... | CRC
  • SOF: start byte, 0xAA
  • LEN: number of bytes starting at OPCODE and ending at the last payload byte
  • CRC: CRC-8 over LEN and all bytes from OPCODE through payload

CRC-8 uses polynomial 0x07, initial value 0x42.

Responses

Responses use the same format. The response opcode is OPCODE | 0x80 and the first response payload byte is a status code:

  • 0x69 OK
  • 0x01 BAD_LEN
  • 0x02 BAD_OPCODE

Supported commands

SET_SPEED (0x01)

Request payload:

uint8 motorId, int16 speed

Signed values map to direction. Range is -255..255. Magnitude maps to PWM 0..255.

Response payload:

status

GET_COUNTS (0x02)

Request payload: none.

Response payload:

status, int32 countA, int32 countB

Counts are little-endian.

SET_COUNTS (0x03)

Request payload:

uint8 motorId, int32 count

Use motorId 0 or 1. Use count = 0 to reset.

Response payload:

status

GET_PIN_STATES (0x04)

Request payload: none.

Response payload:

status, uint8 mask

Bit mapping:

  • bit0 IN1
  • bit1 IN2
  • bit2 IN3
  • bit3 IN4
  • bit4 ENA
  • bit5 ENB

GET_VERSION (0x05)

Request payload: none.

Response payload:

status, uint8 major, uint8 minor, uint8 patch

Example frames

All hex values are bytes in wire order.

SET_SPEED (motorId=1, speed=10% ~= 26)

AA 04 01 01 1A 00 27

SET_SPEED (motorId=1, speed=0)

AA 04 01 01 00 00 F2

GET_COUNTS

AA 01 02 1B

SET_COUNTS (motorId=1, count=0 reset)

AA 06 03 01 00 00 00 00 D5

Notes

  • SPI slave responds on subsequent clocks. The host should send a request frame, then perform a second SPI transfer to read the response frame.
  • For I2C, the response is served on the next master read after a complete request frame is received.

Encoder Self-Test Firmware (Alternative Main)

An alternative firmware entry point exists at src/main_encoder_self_test.cpp. This build is dedicated to encoder validation and does not run the framed protocol handler.

Behavior:

  • Tests both motors in both directions.
  • Uses a short full-power kick before the configured test speed.
  • Samples encoder counts every 100 ms.
  • Stops motor, computes delta, and prints PASS or FAIL to Serial.
  • Repeats continuously.

Build/upload this firmware using the dedicated environment:

platformio run -e nanoatmega328_encoder_test --target upload

Open a serial monitor at 115200 baud to watch results:

platformio device monitor -p /dev/ttyUSB0 -b 115200

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages