New Control board for ODrive Robotics

Success with my ODrive board, replaced due to a fault. Video shows them working independently – not at full power yet!

Test of ODrive motors and Board

Motors and Prototyping

After some experimentation with tiny N20 5V DC motors, the same type found in MG905 servos – I realise that they run just too fast. For the DC motor to work I have used a small 2N7000 / 2N7002 / NDS7002A — N-Channel Mosfet.

I will use a few of these DC motors in the forthcoming installation for the final project, however, because the RPM is too fast,  I will be converting some of the servos I have into continuous and much slower, rotating servos.

This is achieved by cutting the physical obstruction on the main gear and disconnecting the potentiometer inside, replacing with  2 x 2.2K ohm resistors as voltage divider. I have also tested the more reliable MG906 metal gear servo with the PCA9685 16 channel controller board with an Arduino Uno. I drive the board with a 10A 5V fanless power supply with my own printed enclosure holding a dual pole 30A 240V switch.

I will now be looking at converting as many of the plastic geared servos as possible using surface mount 2.2K ohm resistors (+/- 1% accurate), on order from RS Components ; 100 for 70p!

Heres a short clip of 3 motors in action:

Its been a while…

Hello – just to let you know what I am working on…

I am trying out a few things and they include

Lidar – Neato’s Lidar sensor connected to..

Raspberry Pi

Robot Operating System (ROS)

cutecom to talk to the

Lidar Controller from GetSurreal.com

and tmux to facilitate dual screen operations and more

using rviz to display map of the room (up to 5 metres away)

prototyping control of Lidar unit using Arduino Mega

Aquired a Tripmate Router/NAS/Powerbank to avoid the university wifi

Installed different versions of Linux

(i) Ubuntu Mate (with ROS)

(ii) Raspbian Jesse (installed Processing and OpenFrameworks)

difficulty on combining OF and ROS! (help)

if I cant, I will use OSC and two Pi’s; one to sense the Lidar and the other to process in OpenFrameworks.

Any comments (not spam please) welcome! Thanks.

 

 

Final Show – notes pw: physical comp tutor

 

End of Year Project

Introduction

 

I have looked into these areas so far;

  1. Autonomous robot with lidar sensor – no actual purpose, perhaps avoidance of objects in a room, mapping area etc.

 

Further extension of idea – automaton riding on the mobile vehicle, interactive with onlookers

 

Pros:

I will learn a lot and it may result in an impressive installation

I ordered the parts anyway, I was curious and will continue with it in my own time anyway

 

Cons:

Seems like a huge learning curve to throw all these paths into one project.

Is it art or an engineering project?

Terrifying learning curve

2. Small, not micro robot(s) large enough to mount small motors, scaled up into 5-10 robots to investigate flocking behaviours, emergence.

 

Pros:

Good project to push computational content

 

Cons

Not very interesting, been done loads of times already, e.g. 1000 micro robot emergence flocking project by MIT[1] other methods using overhead sensor [1] ref on plans at Github here[1][1]

3. Using O-Drive and powerful brushless motors to animate a fast moving fully enclosed sculpture. E.g. dangerous sharp objects narrowly missing each other enclosed in a Perspex case.

 

Cons:

minimal computational content, unlikely to progress with this.

Parts already sourced in any case.

 

Pros:

Startling and highly dramatic piece, interesting.

 

1.1

Lidar and ROS operating system, investigate this with ODrive [1]motor driver board and Lidar control board [1]

 

1.2 Cartographer [1] and SLAM [1]library; Google’s mapping open source code for Lidar.

 

1.2.1

Useful course on SLAM and introduction to robot mapping

 

1.3 ROS [1]Robot Operating System (best installed in Linux Ubuntu[1])

 

2.1

Investigate further into I2C and AtTiny with small battery, continuous rotating modified micro servos for power.

 

https://www.youtube.com/watch?v=V5vpwVFMPqs

https://en.wikipedia.org/wiki/Alice_mobile_robot

 

[1] https://github.com/ShapeLab/SwarmUI

[1] https://github.com/swarminterface/Zooids

[1] https://odriverobotics.com/

[1] https://www.getsurreal.com/product/lidar-controller-v2-0/

[1] https://opensource.googleblog.com/2016/10/introducing-cartographer.html

[1] https://en.wikipedia.org/wiki/Simultaneous_localization_and_mapping

[1] http://www.ros.org/

[1] https://ubuntu-mate.org/raspberry-pi/

Prototyping for Term2 project

Testing the mechanism and stepper driver with an EasyDriver. I have used a LN298N H bridge board but I found the latter method less bulky and convenient. I am going to introduce a second stepper to incorporate movement about the y axis to move my object.

The supported object is heavy so I have to test the Nema17 stepper to see if it is strong enough.

AtTiny85 With mini Joystick

ATiny is a great little chip, low power, cheap to set up and compact. No Serial.prinln is available however so all testing is done on an Arduino Classic.

I tried out a little joystick I bought as a ‘bundle’ of sensors etc from China.

Fairly simple, using a more limited array of pins to connect to; two pulse width modulated pins and the rest as disgital pins (or use the PWM pins if you want.)

I used two digital pins and two PWM pins (see Fritzing diagrams)

I made a programmer board to plug into the Arduino as this was easier to carry about and re-use. Credit to Brian  Lough on YouTube. Really Good Video.

Video and more pics to be uploaded  very soon!

ATTiny85

Examining the low ‘minified’ ATtiny85 chip, this provides a cut down version of the Arduino; using much less current and only about £1 in cost.

I connected up the ATTiny to an Arduino to burn the bootloader – this allows other programs to be loaded up afterwards. I also made a harness – dedicated, soldered circuit to simplify future programmingof the ATTiny without wiring up a breadboard each time.

Once the bootloader is loaded, I upload the ‘Blink’ sketch to prove it works.

Here is the pcb I made to program the ATTiny, it plugs on top of the Arduino.

underneath! Filed down solder to make a good connection to Ardiuino…

And Attached 3 LEDs to blink

Schematic for programmer shield

 

 

Proposal for End of Term Project: Sand Plotter

Introduction

Many designs of sand plotters are found on the Internet. When I first thought of doing this, I was unaware of how well trodden the path is, however I am not discouraged because it will be a good test of fabrication and still leave plenty of scope for designing patterns that can also be interactive to external environmental factors.

Movement or sound could modify the emerging pattern of the plotter, which may run continuously for extended periods. Thus, patterns can be drawn in a circular (it could be square also) enclosed chamber with a steel ball or cylinder.

Construction

Under the enclosed chamber is a revolving double rail, powered by a high torque stepper motor. The double rail will have a magnet mounted, pulled in the y axis by another stepper motor. The control board will be an Arduino mega with a Ramps shield board (or similar) comprising polulu stepper drivers.

So, with one circular motion and one lateral motion, circular patterns can be drawn in the sand.

Software to control the Ramps board will be developed and also some runtime scripts developed to demonstrate the sand plotter.

Prototype

First stage will be to construct a frame without enclosure, mounting the mechanical parts. A very simple test script to move the turntable and lateral axis with be the first stage.

Second stage is to provide accurate control of the stepper motors

Third stage is to fabricate the sand enclosure and outer box (laser cut)

Fourth stage (possibly too much in the time alotted) – to build some interactivity with external sensors, thus modulating the sand pattern in real time.

Dimensions

I do not want to build anything too large, it becomes impractical, however it must be large enough to look impressive in a gallery setting. So, at least 50 cms diameter.

Examples:

I am not the first…

https://youtu.be/7SyORW-bhLQ

http://forums.jjrobots.com/forum-34.html

Main Parts list:

Laser cut enclosure

Bearings for circular movement

2 x Nema high torque stepper motors

toothed belt, possibly 3d printed gears, metal belt pulleys,steel rods and linear bearings (I have most of these parts from building a 3d printer)

limit switches – these may not be mechanical but optical sensors

Ramps shield and Arduino Mega, polulu stepper drivers

Steel rods and 3d printed supports

Neodymium magnet

15-20 mm diameter steel ball

Neopixel ring Compass Road Safety Dog Jacket

Abandoned the waterproof sleeves idea and decided to do more sewing, not pvc/plastic welding. (from previous blog post)

My dog Baxter is an excellent model and his old coat is never used because he hates wearing it, so I gathered my Arduino Liliypad, compass sensor and other materials listed here:

Bill of Materials: waterproof.fzz

/Users/jtreg/gold/physical/waterproof.fzz

Friday, February 9 2018, 09:35:35
Assembly List
Label Part Type Properties
Part1 Lilypad Arduino Board type Lilypad Arduino
Part2 Seven-Segment LED Backpack 1.2 Inch Digits variant Red; part # 1270
Part3 16 NeoPixel Ring variant variant 1; part # 1463
Part4 FTDI Basic Programmer type Basic; voltage 5V
Real Time Clock ZS-042 RTC Module chip DS3231; variant variant 4
U1 HMC5883L package 16lpcc; axis 3; variant smd
U2 LIPO-2000mAh package lipo-2000; variant 2000mAh
Shopping List
Amount Part Type Properties
1 Lilypad Arduino Board type Lilypad Arduino
1 Seven-Segment LED Backpack 1.2 Inch Digits variant Red; part # 1270
1 16 NeoPixel Ring variant variant 1; part # 1463
1 FTDI Basic Programmer type Basic; voltage 5V
1 ZS-042 RTC Module chip DS3231; variant variant 4
1 HMC5883L package 16lpcc; axis 3; variant smd
1 LIPO-2000mAh package lipo-2000; variant 2000mAh
(I used a 2 x aaa battery as well)

Exported with Fritzing 0.9.3- http://fritzing.org

I tried out the compass code (other components plugged into breadboard, please ignore them!)

I have not yet integrated the real time clock into the project as I ran out of time. I will be usig the pixel ring to add hour, minute and second pixel to flash up.

Originally I planned to use a 7 segment display for the time and temperature
but I think the part I had was faulty. Additional functions could incorporate the temp display off the real time clock…

A little Evo-Stick on the end of electric thread stops it unravelling and helps thread through tiny component holes…

External USB power socket

LilyPad sewn in!

Power test

Added compass chip

Real time clock, battery. I ran out of electric thread so I used light wiring sewn down instead.

ready for walkies

My patient model. Extra waterproof to protect components in rain. Best results after dark!

 

Listing for Lilypad (work in progress)

/*

James Tregaskis

NeoPixel ring for dog jacket
—————————-
9th Feb 2018
This is code I used from two sources and merged them
I have not yet integrated the real time clock into the
project as I ran out of time. I will be usig the pixel
ring to add hour, minute and second pixel to flash up.
Originally I planned to use a 7 segment display for the time and temp
but I think the part I had was faulty.
Additional functions could incorporate the temp display off the real
time clock

Bill of Materials: waterproof.fzz

/Users/jtreg/gold/physical/waterproof.fzz

Friday, February 9 2018, 09:35:35
Assembly List
Label Part Type Properties
Part1 Lilypad Arduino Board type Lilypad Arduino
Part2 Seven-Segment LED Backpack 1.2 Inch Digits variant Red; part # 1270
Part3 16 NeoPixel Ring variant variant 1; part # 1463
Part4 FTDI Basic Programmer type Basic; voltage 5V
Real Time Clock ZS-042 RTC Module chip DS3231; variant variant 4
U1 HMC5883L package 16lpcc; axis 3; variant smd
U2 LIPO-2000mAh package lipo-2000; variant 2000mAh

Shopping List
Amount Part Type Properties
1 Lilypad Arduino Board type Lilypad Arduino
1 Seven-Segment LED Backpack 1.2 Inch Digits variant Red; part # 1270
1 16 NeoPixel Ring variant variant 1; part # 1463
1 FTDI Basic Programmer type Basic; voltage 5V
1 ZS-042 RTC Module chip DS3231; variant variant 4
1 HMC5883L package 16lpcc; axis 3; variant smd
1 LIPO-2000mAh package lipo-2000; variant 2000mAh
(I used a 2 x aaa battery as well)

Exported with Fritzing 0.9.3- http://fritzing.org

*/
/***************************************************************************
This is a library example for the HMC5883 magnentometer/compass

Designed specifically to work with the Adafruit HMC5883 Breakout
http://www.adafruit.com/products/1746

*** You will also need to install the Adafruit_Sensor library! ***

These displays use I2C to communicate, 2 pins are required to interface.

Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!

Written by Kevin Townsend for Adafruit Industries with some heading example from
Love Electronics (loveelectronics.co.uk)

This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

***************************************************************************/

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
#include “ds3231.h”
#define BUFF_MAX 128
uint8_t time[8];
char recv[BUFF_MAX];
long previousMillis = 0;
//long interval = 1000;
unsigned int recv_size = 0;
unsigned long prev, interval = 5000;
boolean doFunkyThings = false;
/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
#include <Adafruit_NeoPixel.h>

#define PIN 3

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_RGB + NEO_KHZ400);

int fixedHeadingDegrees; // Used to store Heading value
float headingDegrees = 0;//heading * 180 / M_PI;
void displaySensorDetails(void)
{
sensor_t sensor;
mag.getSensor(&sensor);
Serial.println(“————————————“);
Serial.print (“Sensor: “); Serial.println(sensor.name);
Serial.print (“Driver Ver: “); Serial.println(sensor.version);
Serial.print (“Unique ID: “); Serial.println(sensor.sensor_id);
Serial.print (“Max Value: “); Serial.print(sensor.max_value); Serial.println(” uT”);
Serial.print (“Min Value: “); Serial.print(sensor.min_value); Serial.println(” uT”);
Serial.print (“Resolution: “); Serial.print(sensor.resolution); Serial.println(” uT”);
Serial.println(“————————————“);
Serial.println(“”);
delay(500);
}

void setup(void)
{
Serial.begin(9600);
Serial.println(“HMC5883 Magnetometer Test”); Serial.println(“”);

/* Initialise the sensor */
if (!mag.begin())
{
/* There was a problem detecting the HMC5883 … check your connections */
Serial.println(“Ooops, no HMC5883 detected … Check your wiring!”);
while (1);
strip.begin();
strip.setBrightness(30); //adjust brightness here
strip.show(); // Initialize all pixels to ‘off’
/* Display some basic information on this sensor */

}
// clock stuff
DS3231_init(DS3231_INTCN);
memset(recv, 0, BUFF_MAX);
Serial.println(“GET time”);
//
strip.begin();
strip.setBrightness(30); //adjust brightness here
strip.show(); // Initialize all pixels to ‘off’
displaySensorDetails();
colorWipe(strip.Color(255, 0, 0), 0);
}

void loop(void)
{
unsigned long currentMillis = millis();
/* Get a new sensor event */
sensors_event_t event;
mag.getEvent(&event);

/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
// Serial.print(“X: “); Serial.print(event.magnetic.x); Serial.print(” “);
// Serial.print(“Y: “); Serial.print(event.magnetic.y); Serial.print(” “);
// Serial.print(“Z: “); Serial.print(event.magnetic.z); Serial.print(” “); Serial.println(“uT”);

// Hold the module so that Z is pointing ‘up’ and you can measure the heading with x&y
// Calculate heading when the magnetometer is level, then correct for signs of axis.
float heading = atan2(event.magnetic.y, event.magnetic.x);

// Once you have your heading, you must then add your ‘Declination Angle’, which is the ‘Error’ of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: -13* 2′ W, which is ~13 Degrees, or (which we need) 0.22 radians
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
float declinationAngle = 0.22;
heading += declinationAngle;

// Correct for when signs are reversed.
if (heading < 0)
heading += 2 * PI;

// Check for wrap due to addition of declination.
if (heading > 2 * PI)
heading -= 2 * PI;

// Convert to degrees
float headingDegrees = heading * 180 / M_PI;

// To Fix rotation speed of HMC5883L Compass module
if (headingDegrees >= 1 && headingDegrees < 240)
{
fixedHeadingDegrees = map (headingDegrees * 100, 0, 239 * 100, 0, 179 * 100) / 100.00;
}
else {
if (headingDegrees >= 240)
{
fixedHeadingDegrees = map (headingDegrees * 100, 240 * 100, 360 * 100, 180 * 100, 360 * 100) / 100.00;
}
}
int headvalue = fixedHeadingDegrees / 18;
int ledtoheading = map(headvalue, 0, 15, 15, 0);

// Serial.print(“Heading (degrees): “); Serial.print(“ledtoheading : “); Serial.print(ledtoheading); Serial.println(headingDegrees);
if (currentMillis – previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
doFunkyThings = !doFunkyThings;
}
doClockStuffi.nLoop();
if (!doFunkyThings) {
funky();
}
else {
colorWipe(strip.Color(0, 0, 255), 0);

if (ledtoheading == 0) {
strip.setPixelColor(15, 255, 0, 50); //Red
strip.setPixelColor(0, 0, 255, 0); //Green
strip.setPixelColor(14, 0, 255, 0); //Green

}
else {
if (ledtoheading == 15) {
strip.setPixelColor(0, 255, 0, 50); //Red
strip.setPixelColor(15, 0, 255, 0); //Green
strip.setPixelColor(1, 0, 255, 0); //Green
}
else {
strip.setPixelColor(ledtoheading, 255, 0, 50); //Red
strip.setPixelColor(ledtoheading + 1, 0, 255, 0); //Green
strip.setPixelColor(ledtoheading – 1, 0, 255, 0); //Green

}
}
}

strip.setBrightness(50);
strip.show();
delay(100);
}
void colorWipe(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void doClockStuffinLoop() {
char in;
char buff[BUFF_MAX];
unsigned long now = millis();
struct ts t;

// show time once in a while
if ((now – prev > interval) && (Serial.available() <= 0)) {
DS3231_get(&t);

// there is a compile time option in the library to include unixtime support
#ifdef CONFIG_UNIXTIME
snprintf(buff, BUFF_MAX, “%d.%02d.%02d %02d:%02d:%02d %ld”, t.year,
t.mon, t.mday, t.hour, t.min, t.sec, t.unixtime);
#else
//Serial.println(“here it is..”);
snprintf(buff, BUFF_MAX, “%d.%02d.%02d %02d:%02d:%02d”, t.year,
t.mon, t.mday, t.hour, t.min, t.sec);
#endif

Serial.println(buff);
prev = now;
}

if (Serial.available() > 0) {
in = Serial.read();

if ((in == 10 || in == 13) && (recv_size > 0)) {
parse_cmd(recv, recv_size);
recv_size = 0;
recv[0] = 0;
} else if (in < 48 || in > 122) {
; // ignore ~[0-9A-Za-z] } else if (recv_size > BUFF_MAX – 2) { // drop lines that are too long
// drop
recv_size = 0;
recv[0] = 0;
} else if (recv_size < BUFF_MAX – 2) {
recv[recv_size] = in;
recv[recv_size + 1] = 0;
recv_size += 1;
}

}
}
void funky() {
// Some example procedures showing how to display to the pixels:
// colorWipe(strip.Color(255, 0, 0), 50); // Red
// colorWipe(strip.Color(0, 255, 0), 50); // Green
// colorWipe(strip.Color(0, 0, 255), 50); // Blue
rainbow(1);
rainbowCycle(1);
}

void rainbow(uint8_t wait) {
uint16_t i, j;

for (j = 0; j < 256; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
}
}
void parse_cmd(char *cmd, int cmdsize)
{
uint8_t i;
uint8_t reg_val;
char buff[BUFF_MAX];
struct ts t;

//snprintf(buff, BUFF_MAX, “cmd was ‘%s’ %d\n”, cmd, cmdsize);
//Serial.print(buff);

// TssmmhhWDDMMYYYY aka set time
if (cmd[0] == 84 && cmdsize == 16) {
//T355720619112011
t.sec = inp2toi(cmd, 1);
t.min = inp2toi(cmd, 3);
t.hour = inp2toi(cmd, 5);
t.wday = cmd[7] – 48;
t.mday = inp2toi(cmd, 8);
t.mon = inp2toi(cmd, 10);
t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
DS3231_set(t);
Serial.println(“OK”);
} else if (cmd[0] == 49 && cmdsize == 1) { // “1” get alarm 1
DS3231_get_a1(&buff[0], 59);
Serial.println(buff);
} else if (cmd[0] == 50 && cmdsize == 1) { // “2” get alarm 1
DS3231_get_a2(&buff[0], 59);
Serial.println(buff);
} else if (cmd[0] == 51 && cmdsize == 1) { // “3” get aging register
Serial.print(“aging reg is “);
Serial.println(DS3231_get_aging(), DEC);
} else if (cmd[0] == 65 && cmdsize == 9) { // “A” set alarm 1
DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
//ASSMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] – 48) * 10 + cmd[2 * i + 2] – 48; // ss, mm, hh, dd
}
uint8_t flags[5] = { 0, 0, 0, 0, 0 };
DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
DS3231_get_a1(&buff[0], 59);
Serial.println(buff);
} else if (cmd[0] == 66 && cmdsize == 7) { // “B” Set Alarm 2
DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
//BMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] – 48) * 10 + cmd[2 * i + 2] – 48; // mm, hh, dd
}
uint8_t flags[5] = { 0, 0, 0, 0 };
DS3231_set_a2(time[0], time[1], time[2], flags);
DS3231_get_a2(&buff[0], 59);
Serial.println(buff);
} else if (cmd[0] == 67 && cmdsize == 1) { // “C” – get temperature register
Serial.print(“temperature reg is “);
Serial.println(DS3231_get_treg(), DEC);
} else if (cmd[0] == 68 && cmdsize == 1) { // “D” – reset status register alarm flags
reg_val = DS3231_get_sreg();
reg_val &= B11111100;
DS3231_set_sreg(reg_val);
} else if (cmd[0] == 70 && cmdsize == 1) { // “F” – custom fct
reg_val = DS3231_get_addr(0x5);
Serial.print(“orig “);
Serial.print(reg_val, DEC);
Serial.print(“month is “);
Serial.println(bcdtodec(reg_val & 0x1F), DEC);
} else if (cmd[0] == 71 && cmdsize == 1) { // “G” – set aging status register
DS3231_set_aging(0);
} else if (cmd[0] == 83 && cmdsize == 1) { // “S” – get status register
Serial.print(“status reg is “);
Serial.println(DS3231_get_sreg(), DEC);
} else {
Serial.print(“unknown command prefix “);
Serial.println(cmd[0]);
Serial.println(cmd[0], DEC);
}
}