Skip to content

Commit

Permalink
major rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
berrak committed Aug 12, 2022
1 parent 294ce42 commit 95fd289
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 66 deletions.
117 changes: 61 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,62 @@
[![GitHub issues](https://img.shields.io/github/issues/berrak/My_Macros.svg?logo=github&logoColor=ffffff)](https://github.com/berrak/My_Macros/issues)
[![Codacy grade](https://img.shields.io/codacy/grade/05e2e79ae90d4b9489689f918ad2ccb5.svg?logo=codacy&logoColor=ffffff)](https://www.codacy.com/app/berrak/My_Macros)

# Arduino library My Macros
`My_Macros` library allows identifying boards that you own. The library maintains *personal macros* for your unique collection of boards. The existing Arduino library `Boards Identify` aims to identify many Arduino-compatible boards. This library, `My Macros,` adds a separate header file with a *personal* list of boards in your possession.
# Arduino library MyMacros
`MyMacros` library allows identifying boards that you own. The library maintains *personal macros* for your unique collection of boards. The existing Arduino library `Boards Identify` aims to identify many Arduino-compatible boards. This library, `MyMacros,` adds a separate header file with a *personal* list of boards in your possession.

Another advantage of this library is that it gives us development flexibility when working in parallel with various boards. Using symbolic links for specific boards minimizes code duplication.
Another advantage of this library is that it gives us development flexibility when working in parallel with various boards. Using `symbolic links` for specific boards minimizes code duplication. The solution discussed can be implemented on `Linux` and `Mac OS X`.

## How to Install

### First method

For details on how to install libraries in the Arduino IDE, please see the [Arduino website](https://www.arduino.cc/en/Guide/Libraries). It is worthwhile reading.

### Second method

1. Navigate to the [Releases page](https://github.com/berrak/My_Macros/releases).
1. Download the latest released ZIP-archive in `~/Arduino/libraries` or any other folder.
1. Rename the file, i.e. remove *master* like this `My_Macros.zip`.
1. In the Arduino IDE, navigate to `Sketch->Include Library->Add .ZIP Library...` and select the file.
1. Arduino IDE will expand the ZIP-archive, but read more about Arduino's usage of libraries in the *First method*.
1. Download the latest released ZIP-archive in `~/Arduino/libraries`.
1. Unzip the archive.
1. Rename the new directory. Remove *version-code*, or *master* in the name like this for `MyMacros`.
1. Restart Arduino IDE.
1. In Arduino IDE scroll down the long list below `Sketch->Include Library` and find `MyMacros`.

For all the details on how to install libraries in the Arduino IDE, please see the [Arduino website](https://www.arduino.cc/en/Guide/Libraries). It is worthwhile reading.

## Examples

Find a code example in Arduino IDE under `File->Examples->My_Macros`.
In Arduino IDE scroll down the long list below `File->Examples` and find `MyMacros`.

Firstly, you must include the library in your sketch:
```cpp
#include <My_Macros.h>
#include <MyMacros.h>
```
The library expands on `Boards_Identify.h` capabilities, and pulls in the `Board Identify` library as a dependence. This is strictly not required.

## Customizing and protecting your macros

The `My_Macros.h` is by default installed in `~/Arduino/libraries/My_Macros/src/`. Use a local copy to avoid this file being overwritten by Arduino when the library updates. Protect this file and move this to `~/mymacros.` Create a symbolic link to this location. When the library file eventually is overwritten, re-create the link again.
The `MyMacros.h` is installed in `~/Arduino/libraries/MyMacros/src/`. Use a local copy to avoid this file being overwritten by Arduino when the library updates. Protect this file and move this to `~/mymacros.` Create a symbolic link to this location. When the library file eventually is overwritten, re-create the link again.

```
mkdir ~/mymacros
$ cd ~/Arduino/libraries/My_Macros/src
mv My_Macros.h ~/mymacros
$ ln -s ~/mymacros/My_Macros.h My_Macros.h
$ cd ~/Arduino/libraries/MyMacros/src
mv MyMacros.h ~/mymacros
$ ln -s ~/mymacros/MyMacros.h MyMacros.h
$ ls -l
My_Macros.cpp
My_Macros.h -> /home/bekr/mymacros/My_Macros.h
MyMacros.cpp
MyMacros.h -> /home/bekr/mymacros/MyMacros.h
```
Arduino IDE will use your file that was moved to `~/mymacros`.

## Compile time identification

To get a compile-time warning, add this line, before the line `#include <My_Macros.h>`.:
To get a compile-time warning, add this line, before the line `#include <MyMacros.h>`.:
```cpp
#define BOARD_IDENTIFY_WARNING
```
Ensure that `File->Preferences->compiler warnings` is set to *Default* or *All*. It will likely show up quickly in the beginning, in red - as a warning - of all compiled messages fast scrolling down your eyes.

In addition, the output from `My_Macros.h` includes the matching define, for example, `Matched defined(ARDUINO_AVR_UNO)` to remind ourselves what define causes the outcome. These definitions are very useful in the code, and based on that, include, exclude code, or add some macros.
In addition, the output from `MyMacros.h` includes the matching define, for example, `Matched defined(ARDUINO_AVR_UNO)` to remind ourselves what define causes the outcome. These definitions are very useful in the code, and based on that, include, exclude code, or add some macros.

## Add a new Arduino board identification

Being able to output board information to the screen or logs is generally useful. We are indeed working with the right board! This is identical to [Board Identify](https://github.com/MattFryer/Board_Identify) usage.

`My Macros` library uses the namespace `MyMacros` to prevent conflicts with other libraries. You can therefore access the personal list of a board like so. Information about how Arduino uses the label `build.board` can be found in the `boards.txt` as, e.g. `tinypico.build.board=TINYPICO`. Enter `ARDUINO_TINYPICO` for the `define` in `My_Macros.h` to match the new Arduino board.
`MyMacros` library uses the namespace `MyMacros` to prevent conflicts with other libraries. You can therefore access the personal list of a board like so. Information about how Arduino uses the label `build.board` can be found in the `boards.txt` as, e.g. `tinypico.build.board=TINYPICO`. Enter `ARDUINO_TINYPICO` for the `define` in `MyMacros.h` to match the new Arduino board.

```cpp
Serial.print("Board Make: ");
Expand All @@ -73,7 +70,7 @@ Serial.println(MyMacros::model);
Serial.print("Board MCU: ");
Serial.println(MyMacros::mcu);
```
`My Macros` does not use the unique numerical `type` value. Set this value to `0` in the `My_Macros.h`. Note that if the board already exists in `Boards_Identify.h`, you must use that library-defined namespace `BoardsIdentify` like so.
`MyMacros` does not use the unique numerical `type` value. Set this value to `0` in the `MyMacros.h`. Note that if the board already exists in `Boards_Identify.h`, you must use that library-defined namespace `BoardsIdentify` like so.
```cpp
Serial.print("Board Type: ");
Serial.println(BoardIdentify::type);
Expand All @@ -85,21 +82,25 @@ Serial.print("Board MCU: ");
Serial.println(BoardsIdentify::mcu);
```

## Reduce code duplication
# Reduce code duplication

The file system has to have a specific layout to minimize duplication of code effectively. For example, we have created four different directories for our boards and one standard code directory, `CODE,` where all our sketches will live.
The solution discussed here can be implemented on `Linux` and `Mac OS X`, but not on Windows. `Windows Subsystem for Linux 2` can maybe solve this. The file system has to have a specific layout to minimize duplication of code effectively. For example, we have created four different directories for our boards and one standard code directory, `CODE,` where all our sketches will live.

It's probably a good idea to update your sketch folder in `File-> Preferences` with `~/Arduino/CODE.`
It's probably a good idea to update your sketch folder in `File-> Preferences` with `~/Arduino.` Create som directories for your boards.

```
~/Arduino
├── arduinoUno
├── CODE
├── debinixSTM32G031F8
├── lolinESP8266
└── sparkfunESP32
├── D1miniESP8266
├── ESP32TinyPICO
├── libraries
├── STM32G031Fx
└── Uno
```
The organization for sub-folders in `CODE` is very personal. For example, use something in line with Arduino's IDE structure similar to Arduino's `File-> Examples` hierarchy.
The organization for sub-folders in `CODE` is very personal. For example, use something in line with Arduino's IDE structure similar to Arduino's `File-> Examples` hierarchy (analog, basic, communication, digital, display, neopixel, sensors, usb, ...). The drawback with such tree structure is that it becomes profound, and paths get very long.

For example, the idea is to have one typical *Blink* sketch for all our development boards. Thus, when saving the built-in `Blink.ino` sketch say below `CODE,` e.g. `../CODE/basic/blink/blink.ino` but not below any development board directories. The header macros will handle any differences between individual boards.

```
~/Arduino/CODE$ tree -L 1
Expand All @@ -113,36 +114,40 @@ The organization for sub-folders in `CODE` is very personal. For example, use so
├── sensors
└── usb
```
For example, the idea is to have one typical *blink* sketch for all of our development boards. Thus, when saving the built-in` blink.ino` sketch should be below `CODE,` e.g. `../CODE/basic/blink/blink.ino` and is not below any development board directories. The header macros will handle any differences between individual boards.
One solution to `reduce the depth and still have useful symbolic links` is to adapt a sketch naming convention instead. For example, use the camel case naming strategy where the first parts repeat the above hierarchy. Thus the built-in `Blink.ino` is saved as `basicBlink.ino` directly below `CODE`.

## Add a symbolic link (manually) in the device tree to the code directory

Change the folder to one of the development boards and its main directory and create the link to the familiar `blink.ino`.
Change the folder to one of the development boards and its main directory and create the link to the familiar `basicBlink.ino`.
```
$ cd ~/Arduino/debinixSTM32G031F8
$ ln -s ../CODE/basic/blink/blink.ino blink.ino
$ ls -l blink
blink.ino -> ../CODE/basic/blink/blink.ino
$ cd ~/Arduino/STM32G031Fx
$ mkdir basicBlink
$ cd basicBlink
$ ln -s ../../CODE/basicBlink/basicBlink.ino basicBlink.ino
$ ls -l
basicBlink.ino -> ../../CODE/basicBlink/basicBlink.ino
```
We are working in this particular development board directory, but we are editing the typical `blink.ino` file. Define the board macros in the `My_Macros. h' file.
We are working in this particular development board directory, but we are editing the typical `basicBlink.ino` file. Define the board macros in the `MyMacros.h` file. The sketch has its directory, as Arduino requires, and allows adding other files in the same folder.

Change to another development board folder, the main directory, and create a second link to the common `blink.ino`.
Change to another development board folder, the main directory, and create a second link to the common `basicBlink.ino`.
```
$ cd ~/Arduino/lolinESP8266
$ ln -s ../CODE/basic/blink/blink.ino blink.ino
$ ls -l blink
blink.ino -> ../CODE/basic/blink/blink.ino
$ cd ~/Arduino/D1miniESP8266
$ mkdir basicBlink
$ cd basicBlink
$ ln -s ../../CODE/basicBlink/basicBlink.ino basicBlink.ino
$ ls -l
basicBlink.ino -> ../../CODE/basicBlink/basicBlink.ino
```

Reduce the clutter of files, with fewer duplicates in the file system, for files essentially performing the same task.
The above steps are somewhat tedious, but the script `mylink` below becomes effortless.
This concept reduces the clutter of files, with fewer duplicates in the file system, for files essentially performing the same task.

## Automation of link creation

Now we will create a command script called `mylink.` Run this in the development board directory, and this makes a symbolic link.
Now we will create a command script called `mylink`. Run this in the development board directory, and this makes a symbolic link.

## Create the bash command script

Open an editor and copy the content below.
Open an editor and copy the content below. This file is also included in the library in the `script` folder.

```bash
#!/bin/bash
Expand Down Expand Up @@ -196,20 +201,20 @@ $ chmod u+x ~/.local/bin/mylink
Debian/Linux system includes a command called *link*, but `mylink` does the search and link creation operation effortless without specifying paths to any files. Now test the command in a third development board folder with:

```
$ cd ~/Arduino/arduinoUno
$ mylink blink.ino
Check that a symbolic link blink.ino has successfully been created in '~/Arduino/arduinoUno'.
$ ls -l blink
blink.ino -> ../CODE/basic/blink/blink.ino
$ cd ~/Arduino/Uno
$ mylink basicBlink.ino
Check that a symbolic link basicBlink.ino has successfully been created in '~/Arduino/Uno/basicBlink'.
$ ls -l basicBlink
basicBlink.ino -> /home/bekr/Arduino/CODE/basicBlink/basicBlink.ino
```
If you run it without an argument, the command will ask for the name of the sketch.

## Final thoughts

If you set Arduino `File->Preferences` to update libraries at start up, be mindful since you may overwrite the symbolic link to your customizations. In that case, re-create the symbolic link to `~/mymacros`. For planned changes, improvements, and known bugs, please visit the [Github issues tracker](https://github.com/berrak/My_Macros/issues).

The device tree does not maintain the neat hierarchical organization below CODE. Thus, choosing meaningful file names when first saving the file in the CODE-tree is helpful. Another challenge is the regression testing of code written for multiple devices.
The device tree does not maintain the neat hierarchical organization below CODE. Thus, choosing meaningful file names when first saving the file in the CODE-tree is helpful. Another challenge is the regression testing of code written for multiple devices. Traversing the symbolic links for each or a single board during testing is one way to set up tests.

## Credits

Thanks to `Matt Fryer` and his [Board Identify](https://github.com/MattFryer/Board_Identify) and his earlier work.
Thanks to `Matt Fryer` and his [Board Identify](https://github.com/MattFryer/Board_Identify) for his earlier work.
File renamed without changes.
10 changes: 5 additions & 5 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name=My Macros
version=0.2
name=MyMacros
version=0.3
author=Debinix Team <debinixteam@triatagroup.com>
maintainer=Debinix Team <debinixteam@triatagroup.com>
sentence=The Arduino library identifies and adds macros for your unique collection of development boards.
paragraph=By maintaining this list of new or uncommon boards, they can be given macros in an Arduino uniform way.
sentence=The Arduino library identifies your unique collection of development boards.
paragraph=Give board-specific macros to new or uncommon boards. Code can branch depending on identified defined macros and for different development platforms. MyMacros.h file extends the known list from the Board Identify library.
category=Other
url=https://github.com/berrak/My_Macros
architectures=*
includes=My_Macros.h
includes=MyMacros.h
depends=Board Identify
41 changes: 41 additions & 0 deletions script/mylink
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash
#
# mylink - script to find and create a symbolic link to a source Arduino sketch
# Author: Debinix Team (C). License GPL-3.0
# Date: 2022-08-10
#
parent_boards_directory_name="Arduino/CODE"

case $# in
0) echo -n "Give the name of the sketch, including '.ino': "
read fname;;
1) fname=$1
;;
*) echo "Too many arguments given, aborting. Please correct and retry."
exit;;
esac

if echo "$fname" | grep -q "\.ino"; then
echo "Sketch '$fname'"
mydir=$( cut -d '.' -f 1 <<< "$fname" )
else
echo "Missing '.ino' in the sketch name. Please correct and retry."
exit
fi

# Create a subdirectory for Arduino IDE
if [ ! -d "$mydir" ]
then
mkdir $mydir
fi

if [ -h "$PWD/$mydir/$fname" ]
then
echo "A symbolic link with the name '$fname' already exists in '$PWD/$mydir'. Please remove this '$fname'-link, and try again."
exit
fi

# Search below ../CODE i.e for a source sketch to link to for the board's subfolder tree
find "$HOME/$parent_boards_directory_name" -name "$fname" -exec ln -s '{}' "$mydir/$fname" \;
echo "Check that a symbolic link '$fname' has successfully been created in '$PWD/$mydir'."

4 changes: 2 additions & 2 deletions src/My_Macros.cpp → src/MyMacros.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* My_Macros.cpp
* MyMacros.cpp
* This file is not the droid you're looking for.
* An Arduino library which allows grouping of macros for your unique collection of boards.
* The Arduino library identifies your unique collection of development boards.
* Created by Debinix Team (C). Licensed under GPL-3.0.
* Date 2022-08-10.
*/
9 changes: 6 additions & 3 deletions src/My_Macros.h → src/MyMacros.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*
* My_Macros.h
* An Arduino library which allows grouping of macros for your unique collection of boards.
* MyMacros.h
* The Arduino library identifies your unique collection of development boards.
* Created by Debinix Team (C). Licensed under GPL-3.0.
* Date: 2022-08-10.
*/

#pragma once
#ifndef _MyMacros_h_
#define _MyMacros_h_

#include <Board_Identify.h>

Expand Down Expand Up @@ -171,3 +172,5 @@ namespace MyMacros {
const char* mcu = "Unknown";
#endif
}

#endif

0 comments on commit 95fd289

Please sign in to comment.