Go Down

Topic: Examples in the Libraries (Read 182 times) previous topic - next topic

kssoin

I have Arduino 1.8.9. Recently I installed two libraries from Github by cloning them to the libraries folder in the Sketchbook folder that is in the portable folder.
The installation is like this D:/Arduino_1.8.9/>Arduino-1.8.9
                                                                 >portable/Sketchbook/>......
                                                                                                  > libraries
                                                                                                  > hardware
                                                                                                  >.........
These libraries appear as contributed libraries in the Arduino IDE
These two libraries are
  • IRremote             url:  https://github.com/z3t0/Arduino-IRremote.git
  • HD44780Library   url:  https://github.com/positronic57/HD44780Library.git

Both of these have an examples and an example folder respectively.
In the Files>Examples>Examples from custom libraries
Here only IRRemote examples are listed but HD44780Library is not listed

Why is this ?

pert

HD44780Library's example is not a valid Arduino sketch, and so is not recognized by the Arduino IDE. It is a .c file. A valid Arduino sketch consists of at least one .ino file in a folder of the same name. You can have multiple source files in the sketch folder, which will be shown as tabs in the Arduino IDE, but the .ino file is required.

You could definitely adapt the example into an Arduino sketch, since Arduino sketches are compiled as C++ and C is a subset of C++. If you need assistance with that, I can probably help out.

kssoin

HD44780Library's example is not a valid Arduino sketch, and so is not recognized by the Arduino IDE. It is a .c file. A valid Arduino sketch consists of at least one .ino file in a folder of the same name. You can have multiple source files in the sketch folder, which will be shown as tabs in the Arduino IDE, but the .ino file is required.

You could definitely adapt the example into an Arduino sketch, since Arduino sketches are compiled as C++ and C is a subset of C++. If you need assistance with that, I can probably help out.
I compiled the example and have this saved as a arduino sketch in this folder also. It does not show. The library files have .c files perhaps that may be the issue?
Can a xxxx.c file be renamed as xxxx.cpp ?

kssoin

Thanks pert for offering assistance.
Would it be a big ask to rewrite C libraries in C++.
I could give it a try in your guidance.

pert

Can a xxxx.c file be renamed as xxxx.cpp ?
Renaming HD44780.c to HD44780.cpp is probably the most simple approach to making the library's functions usable in C++ code (.ino files of Arduino sketches are compiled as C++ after a little preprocessing).

However, while we're messing with the library anyway, let's use the best practices approach instead. If you wrap C function declarations in extern "C" {}, you can then use them in C++. The idea is to only do this when the declarations are made in a C++ program, so that you don't break the ability to still use the function declarations in C code. To achieve that, we use preprocessor directives:

Open HD44780.h in a text editor.

At line 39, add this code:
Code: [Select]
#ifdef __cplusplus
extern "C" {
#endif


At line 246, add this code:
Code: [Select]
#ifdef __cplusplus
}
#endif


The __cplusplus macro is only defined when compiling C++ code. So that means the extern "C" {} code will not be used when compiling C code.


Now the library is friendly to use in Arduino sketches but we want an example sketch to demonstrate the use of the library. The first step is to use an examples folder name that is compliant with the Arduino library specification. The library uses the folder name example, but the Arduino library specification says it should be named examples. So rename the "example" folder to "examples". A specification-compliant examples folder name is not absolutely necessary with the Arduino IDE (it only causes an extra menu level: File > Examples > HD44780Library > example > libHD44780example) but the incorrect folder name will cause the Arduino Web Editor to not recognize the library you're trying to import and will instead only import the example sketch (which doesn't do much good without the library installed).

The next step is to convert the example into an Arduino sketch. The sketch needs its own folder, under the examples folder. You can name the folder libHD44780example. Then move the file libHD44780example.c to the libHD44780example folder. Finally, rename the file libHD44780example.ino. The folder structure inside the HD44780Library's folder should now look like this:

|_examples
  |_libHD44780example
     |_libHD44780example.ino

At this point, the example is a valid Arduino sketch and will compile no problem (I didn't test it with an LCD). However, it doesn't look like a familiar Arduino sketch because it uses main() instead of the setup() and loop() functions we're used to. The main() function is called once when the program runs. This means the code at the start of the main() function will run once at startup, just like the code in the setup() function of an Arduino sketch, and if you want code to run over and over in a loop (like the loop() function of Arduino sketches), you put it inside of an infinite loop like this:
Code: [Select]
while(1)
 {
          // code to run over and over here
 }


So if you wanted to convert this code to use setup() and loop(), you would move all the code from main() that's outside the while loop to setup() and all the code that's inside the while loop to loop(). In this case there is no code in loop(), so you would leave the loop() function empty:
Code: [Select]
/*
   libHD44780.ino

   Created: 13-Jun-15 13:58:22
   Author: Goce Boshkovski

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

   Example of using HD44780 library on Atmega32.The CPU freq is 4MHz defined with F_CPU.
   JHD 162A 16x2 LCD module is used for the test.

   Connection between MCU and LCD:
   PORTB0 -> LCD D4
   PORTB1 -> LCD D5
   PORTB2 -> LCD D6
   PORTB3 -> LCD D7
   PORTD4 -> LCD RS
   PORTD6 -> LCD R/W
   PORTD7 -> LCD E

*/

#ifndef F_CPU
#define F_CPU 4000000UL
#endif

#include <avr/io.h>
#include "HD44780.h"


void setup() {
  //Define custom special characters. In this example those are Cyrillic letters: sh and d.
  uint8_t specCharMatrix[2][8] = {{0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1F, 0x00}, {0x0E, 0x0A, 0x0A, 0x0A, 0x0A, 0x1F, 0x11, 0x00}};

  TSHD44780 HD44780Display;
  TSHD44780 *pHD44780Display = &HD44780Display;

  /*
   Use:
   - TWO_LINES_DISPLAY to init 2 lines module;
   - FOUR_LINES_DISPLAY to init 4 lines LCD.

   Although single line LCD has only one line for presenting the content,
   the DDRAM memory in most of the modules out there is split in two 8 bytes long buffers.
   Those single line modules must be initialized using TWO_LINES_DISPLAY
   as argument of the init function. If that is not the case use
   SINGLE_LINE_DISPLAY during the init process.

  */
  LCDInit4(pHD44780Display, &PORTD, &PORTB, PD4, PD7, PD6, TWO_LINES_DISPLAY);
  LCDDefineSpecialChars4(pHD44780Display, specCharMatrix, 2);

  LCDSendCommand4(pHD44780Display, DISPLAY_ON);

  LCDShowString4(pHD44780Display, "libHD44780");
  LCDSendCommand4(pHD44780Display, LCD16x2_SELECT_LINE_2);
  LCDShowString4(pHD44780Display, "Tester!!!");

  /*
   To manually set the cursor position in case of single line LCD,
   use the strating addresses of the two 8 bytes
   wide DDRAM memory segments as base addresses.
   LCD16x1_SELECT_DDRAM_1ST_HALF
   LCD16x1_SELECT_DDRAM_2ND_HALF
  */
  LCDSetCursorPosition4(pHD44780Display, LCD16x2_SELECT_LINE_1, 12);
  LCDSendCommand4(pHD44780Display, CURSOR_ON);
  LCDSendCommand4(pHD44780Display, BLINKING_CURSOR_ON);

  //Show the data from the CGRAM
  LCDShowCharacter4(pHD44780Display, 0x00);
  LCDShowCharacter4(pHD44780Display, 0x01);
}


void loop() {
}

Arduino has a main() function tucked away in their core library which calls setup() and loop(). It also initializes the hardware. When you define your own main() in the sketch, that overrides the core library's main, so the hardware is never initialized and some of the standard Arduino are not used. So the above code is not functionally identical to libHD44780.c (compare the compilation sizes if you like). The code in the example libHD44780.c doesn't use any of the standard Arduino API functions, and thus will not be adversely affected by the lack of the hardware initialization. However, the use of setup() and loop() will make the example more suitable to act as a base for Arduino sketches which do use the Arduino functions.

Please let me know if there's anything you don't understand or you run into any problems during the process.

kssoin

#5
Apr 19, 2019, 04:18 pm Last Edit: Apr 19, 2019, 04:22 pm by kssoin
Please let me know if there's anything you don't understand or you run into any problems during the process.
Very lucid description of the process. Its so nice  of you to have compiled the sketch.
I had compiled it for Atmega 328. I use the McuDudes minicore to compile the code and I upload the hex file on a Atmega Dev board using AVRDUDESS. In fact I ran into compiler errors which were cleared up.   
This is athttps://forum.arduino.cc/index.php?topic=610711.0



I will do as described ad update on this post.

Thanks once again pert!

Go Up