12. Output devices

This week I worked on defining my final project idea and started to getting used to the documentation process.

Speaker

A very quick and simple example of output : a speaker. For his low power version, just plug one wire of speaker to GND et the other on one pin.

A little code (get pitches.h here):

/**
 * Play musique with arduino
 * @author Florent Lemaire
 */

#include "pitches.h" // musique
#define speakerPin 3

/*
 * Some musics 
 */
// notes in the melody:
int melodyOk[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurationsOk[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

int melodyKo[] = {
  NOTE_C4, NOTE_G3, NOTE_C4, NOTE_G3
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurationsKo[] = {
  2, 2, 2, 2, 2
};

/*
 * code
 */

void playMusic(int melody[], int noteDurations[]) {
  for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(speakerPin, melody[thisNote], noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(speakerPin);
  }
}

void setup() {
  pinMode(speakerPin, OUTPUT);

}

void loop() {
  delay(5000);
    playMusic(melodyOk, noteDurationsOk);
  delay(5000);
    playMusic(melodyKo, noteDurationsKo);
}

Stepper motor

My motor is a Nema 17 (Hanpose 17HS3401 or this link).

Specification:

Model 17HS3401
Type Hybrid
Phase 2
Step Angle 1.8°
Motor Size 42 x 34mm
Shaft “D” shaft 21 x Ф5mm
Outlet way “4” plug line
Motor leads Dupont line(1M)
Adapter drive Two-phase step drive

Electrical Specifications:

Model No. Step Angle Motor Length Rated Current Resistance /Phase Inductance /Phase Holding Torque Detent Torque Inertia Of Rotor Lead
( °) (L)mm (A) (Ω) (mH) (N.cm) (N.cm) (G. cm²) (No.)
17HS3401 1.8 34 1.3 2.4 2.8 28 1.6 34 4

General Specification:

Precision angle step ±5% (full step, no charge)
Resistance accuracy ±10%
Precision inductance ±20%
Temperature rise 80deg Max (rated current, 2 phase on)
Ambient temperature ( - 20°)-(+ 50°)
Insulation resistance 100MΩ Min, 500VDC
Insultion Force 500VAC for a minute

Using L298N

The wiring

image-20200420171450809

In pictures and video, we can see Arduino is powered by USB. At the end, I use a little tip. In the picture above, you can see a yellow jumper. Normally you set this jumper to plug the 5V converter on the board (only if you go to 12V input max) and avoid you to plug a 5V source. But you can also plug on 5V of the board to drain 5V instead of give power so I plug 5V of he L298N to the Vin of my arduino and I haven’t need to usb anymore !

How to correct wire the nema motor? There’s no rule on colors (When testing my motor I’ve got 1 coil on green + red and the other on blue + black) But finding the coils is easy. Without plugin motor to anything, first try to rotate the motor. Then plug 2 wires together, if the motor is harder to move, you have a coil. If not, try another pair.

I use an arduino Uno and a L298N to drive it. I first use a 12VDC power supply. I take a measure of current, I got 4.1A at the start !!! However the L298N board quickly heats up and gets very hot, I cannot even touch the heat sink. It’s not a good solution!

To measure current, I use my multimeter in serial on the 12V supply of the L298N breakout board.

I made another test with a 9V battery and I’ve got only 0.87A and the L298N didn’t get hot. I it’s think it’s just the limit of the 9V battery.

image-20200420162910680

The code is very simply, I use the Stepper Library included in Arduino IDE. Here it makes 360° in one way, wait 2s, then turn the other way. A step is 1.8°, so it’s 200 steps to make 360°.

#include <Stepper.h>

// Define number of steps per revolution:
const int stepsPerRevolution = 200;
// Initialize the stepper library on pins 8 through 11:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 9, 10, 11);
void setup() {
  // Set the motor speed (RPMs):
  myStepper.setSpeed(100);
}
void loop() {
  // Step one revolution in one direction:
  myStepper.step(200);
  delay(2000);
  // Step on revolution in the other direction:
  myStepper.step(-200);
  delay(2000);
}

Using A4988

I spend too much time on testing screens so no more time for this week.

DC motor

My motor is the 12VDC motor of my final project, I have no specs on it.

Arduino Uno version

I plug a 12VDC power supply to the litter, I get 12V & GND from the 2.54 connector on it. As I explain before, I use 5V for my arduino from the L298 breakout board.

image-20200420185103983

My code :

/**
 * DC motor drive with joystick
 * 
 * @author Florent Lemaire
 */

#define in1 8
#define in2 9
#define enA 6
#define analogInput A0

void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enA, OUTPUT);
  pinMode(analogInput, INPUT);
}

void loop() {
  int xAxis = analogRead(analogInput); // Read Joysticks X-axis
  int motorSpeedA = 0;

  // X-axis used for left and right control
  if (xAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    motorSpeedA = map(xAxis, 470, 0, 0, 255);
  }else 
  if (xAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    motorSpeedA = map(xAxis, 550, 1023, 0, 255);
  }else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor
}

SAMD11C version

I want to use SAMD11C in my final project so I try to drive the motor of my litter with the L298N and my SAMC11C custom board.

I plug 12V to my L298N board, I use the 5V on L298N to power directly my board.

The joystick axis are just potentiometers, I plug it to +3.3V and GND (instead of 5V) because my SAMD11C have a 3.3V input logic.

The code is like Arduino, just change I/O ID.

/**
 * DC motor drive with joystick
 * 
 * @author Florent Lemaire
 */

#define in1 15
#define in2 14
#define enA 5
#define analogInput 2

void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enA, OUTPUT);
  pinMode(analogInput, INPUT);
}

void loop() {
  int xAxis = analogRead(analogInput); // Read Joysticks Y-axis
  int motorSpeedA = 0;

  // X-axis used for left and right control
  if (xAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    motorSpeedA = map(xAxis, 470, 0, 0, 255);
  }else 
  if (xAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    motorSpeedA = map(xAxis, 550, 1023, 0, 255);
  }else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor
}

Driving a nokia 5110 with a SAMD11C

After testing a 2.4” lolin tft screen that are nearly impossible to plug (no enough memory with libraries) I switch to a chineese 5110 screen (a clone of this sparkfun product).

Due to only 12kb available (16 - 4 of the booloader), I bypass use of libraries made for arduino.

Even the first wiring takes time because I’ve only one version of this board in the world.

SAMD11C MPB 5110 board
GND GND
3.3V (not plugged in demo) BL (backlight)
3.3V VCC
4 CLK
2 DIN
25 DC
24 CE
31 RST

I also add a pending wire on pin 28/RST of my board because I use pins that are normally used by USB so I make bridge between 28/RST & GND to reset the µc and have USB back ! Before finding this solution, I lost many times to find a solution because the board cannot be visible in Arduino IDE and I can’t reflash modifications.

To have bitmap data in bytes, I make a b&w picture of the good size (here 84x48px for fullscreen)

Then I go to http://javl.github.io/image2cpp/ and I use these settings :

image-20200421214154800

Then I get the generated byte table and put it in my code :

/**
 * Driving 5110 screen on my SAMD11C board
 * @author Florent Lemaire
 */

#define PIN_SCE   24 //LCD Chip Select
#define PIN_RESET 31 //LCD reset, active low
#define PIN_DC    25 //LCD data/command
#define PIN_SDIN  2 //LCD SPI Mosi
#define PIN_SCLK  4 //LCD SPI clk

//DC pin define if we send data or cmd
#define LCD_COMMAND 0
#define LCD_DATA  1

//LCD size
#define LCD_X     84
#define LCD_Y     48

//This font is 5 pixels (height) x 8 (width)
static const byte ASCII[][5] = {
  {0x00, 0x00, 0x00, 0x00, 0x00} // 20 
  ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
  ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
  ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
  ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
  ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
  ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
  ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
  ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
  ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
  ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
  ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
  ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
  ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
  ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
  ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
  ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
  ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
  ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
  ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
  ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
  ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
  ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
  ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
  ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
  ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
  ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
  ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
  ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
  ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
  ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
  ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
  ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
  ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
  ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
  ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
  ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
  ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
  ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
  ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
  ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
  ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
  ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
  ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
  ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
  ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
  ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
  ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
  ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
  ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
  ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
  ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
  ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
  ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
  ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
  ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
  ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
  ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
  ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
  ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
  ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c backslash
  ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
  ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
  ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
  ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
  ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
  ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
  ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
  ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
  ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
  ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
  ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
  ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
  ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
  ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
  ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
  ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
  ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
  ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
  ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
  ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
  ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
  ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
  ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
  ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
  ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
  ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
  ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
  ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
  ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
  ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
  ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
  ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
  ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
  ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~
  ,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f DEL
};

// A smiley
//504 bytes for 84 x 48 pixels
// 1 byte = 8bits code  8 pixels (0/1) b&w
char smiley[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x30, 0x18, 0x1C,
  0x0C, 0x0C, 0x06, 0x06, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
  0x07, 0x07, 0x0E, 0x06, 0x1C, 0x1C, 0x38, 0x70, 0x70, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0x3C, 0xCE, 0x67, 0x33, 0x18, 0x08,
  0x08, 0xC8, 0xF8, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
  0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x01, 0x07,
  0x0F, 0x3C, 0xF8, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x0C, 0x7F,
  0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x63,
  0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF,
  0xF0, 0x00, 0x00, 0x00, 0x08, 0x08, 0xFC, 0x8C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
  0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
  0x0C, 0x0C, 0x0C, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x3C, 0x70, 0xE0, 0x80, 0x00, 0x07, 0x0C, 0x38, 0x60, 0xC0,
  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0,
  0xF0, 0xE0, 0xC0, 0x80, 0xC0, 0x30, 0x18, 0x0F, 0x00, 0x00, 0x80, 0xC0, 0x70, 0x3C, 0x1F, 0x07,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06,
  0x0E, 0x1C, 0x18, 0x38, 0x31, 0x73, 0x62, 0x66, 0x64, 0xC7, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
  0xC7, 0xC7, 0xC7, 0x67, 0x63, 0x63, 0x71, 0x30, 0x38, 0x18, 0x1C, 0x0C, 0x06, 0x03, 0x03, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
};

// agrilab logo, 84x48px
char agrilab[] = {
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x1f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0x3f, 0xff, 0xff, 0xff, 0xff, 
  0x03, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x03, 0x03, 0x03, 0x07, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xe1, 0x80, 0x80, 0xc0, 0xff, 0x0f, 0x07, 0x03, 0x01, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 
  0x0f, 0x07, 0x07, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x03, 0x00, 0x00, 0x00, 0xf0, 
  0x00, 0x00, 0x00, 0x03, 0x7f, 0xff, 0x0f, 0x03, 0x01, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x01, 
  0xff, 0x03, 0x01, 0x00, 0x00, 0xc0, 0x80, 0xc1, 0xe7, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 
  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x80, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x01, 0xff, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x80, 0x00, 0x01, 0x01, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x3f, 
  0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 
  0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x7f, 0x01, 0x00, 0x00, 0x60, 0x00, 
  0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xff, 
  0xff, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfc, 0xfc, 0xff, 0xff, 
  0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, 0x3c, 
  0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x80, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 
  0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 
  0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xff, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 
  0xf8, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xfc, 0xf8, 0xfc, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xf8, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf8, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

void setup(void) {
  LCDInit();
  Serial.begin(9600);
}

void loop(void) {
  LCDClear();
  LCDBitmap(smiley);
  delay(2000);

  LCDClear(); 
  LCDBitmap(agrilab);
  delay(2000);

  LCDClear();
  LCDString("agrilabBoard"); //1 line of 12 char
  LCDString("|...........");  //6 lines by screen
  LCDString("            "); 
  LCDString("  Bonjour   ");   //message de texte
  LCDString("  Florent   "); 
  LCDString("____________"); 
  delay(1000);  //2 sec
}

// Fonction gotoXY
void gotoXY(int x, int y) {
  LCDWrite(0, 0x80 | x);  // Column.
  LCDWrite(0, 0x40 | y);  // Row.
}

// draw bitmap on screen
void LCDBitmap(char my_array[]){
  for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++)
    LCDWrite(LCD_DATA, my_array[index]);
}

// draw char using ascii table
void LCDCharacter(char character) {
  LCDWrite(LCD_DATA, 0x00); //empty left column to split

  for (int index = 0 ; index < 5 ; index++)
    LCDWrite(LCD_DATA, ASCII[character - 0x20][index]); // 0x20 for space

  LCDWrite(LCD_DATA, 0x00); //empty right column for split
}

// draw string
void LCDString(char *characters) {
  while (*characters)
    LCDCharacter(*characters++);
}

// clear LCD by writing zeros
void LCDClear(void) {
  for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++)
    LCDWrite(LCD_DATA, 0x00);

  gotoXY(0, 0); //Puis revenir en haut
}

//init LCD
void LCDInit(void) {

  // setting pins
  pinMode(PIN_SCE, OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC, OUTPUT);
  pinMode(PIN_SDIN, OUTPUT);
  pinMode(PIN_SCLK, OUTPUT);

  //Reset the LCD
  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);

  LCDWrite(LCD_COMMAND, 0x21); //Tell LCD that extended commands follow
  LCDWrite(LCD_COMMAND, 0xB0); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
  LCDWrite(LCD_COMMAND, 0x04); //Set Temp coefficent
  LCDWrite(LCD_COMMAND, 0x14); //LCD bias mode 1:48: Try 0x13 or 0x14

  LCDWrite(LCD_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
  LCDWrite(LCD_COMMAND, 0x0C); //Set display control, normal mode. 0x0D for inverse
}

// send data or command (low = command / high = data)
void LCDWrite(byte data_or_command, byte data) {
  digitalWrite(PIN_DC, data_or_command);
  digitalWrite(PIN_SCE, LOW);
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
  digitalWrite(PIN_SCE, HIGH);
}

A final picture, I made a quick dirty wiring for backlight ^^

Resources

https://www.makerguides.com/l298n-stepper-motor-arduino-tutorial/

https://www.arduino.cc/en/Tutorial/ToneMelody?from=Tutorial.Tone

https://learn.sparkfun.com/tutorials/graphic-lcd-hookup-guide

http://electroniqueamateur.blogspot.com/2018/12/afficheur-lcd-nokia-5110-et-arduino.html

http://tiptopboards.free.fr/arduino_forum/viewtopic.php?f=2&t=21#

Attachments

Driving DC motor with arduino DCdriveSAMD.ino

Driving DC motor with SAMD11C DCdrive.ino

Playing music music.zip

5110 with SAMD 5110LCD_SAMD.ino

Driving stepper motor with arduino stepper.ino