Difference between revisions of "Programming"

From The TinkerNet Wiki
Jump to navigation Jump to search
 
(5 intermediate revisions by the same user not shown)
Line 64: Line 64:
 
===Memory Saving===
 
===Memory Saving===
 
[https://playground.arduino.cc/Main/PROGMEM PROGMEM]
 
[https://playground.arduino.cc/Main/PROGMEM PROGMEM]
 +
 +
===Some Libraries to Check Out===
 +
 +
*[https://github.com/thomasfredericks/Bounce2 Bounce2]
 +
*[https://github.com/JChristensen/JC_Button JC Button]
 +
*
  
 
=='''STUPID''' Library Compile Warnings!!!==
 
=='''STUPID''' Library Compile Warnings!!!==
 +
Dear library writers,
 +
 +
Please fully debug your code before release.
 +
 +
It's not THAT difficult.  Really.
 +
 +
I fully understand that compiler warnings do not indicate that your code will not work as expected, BUT, compiler warnings during a build are rather disconcerting.
 +
 
===Arduino Libraries===
 
===Arduino Libraries===
 
====PubSubClient (2.8.0)====
 
====PubSubClient (2.8.0)====
Line 77: Line 91:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''FIX:''' Add <code>unsigned</code> to the definition of <code>expectedLength</code> on line 487
+
'''FIX:''' Add <code>unsigned</code> to the definition of <code>expectedLength</code> on line 487 of '''PubSubClient.cpp'''
  
 
====SimpleTimer (0.0.0-alpha+sha.b30890b8f7)====
 
====SimpleTimer (0.0.0-alpha+sha.b30890b8f7)====
Line 89: Line 103:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''FIX:''' Add <code>unsigned</code> to the definition of <code>delays[]</code> on line 106 of <code>SimpleTimer.h</code>
+
'''FIX:''' Add <code>unsigned</code> to the definition of <code>delays[]</code> on line 106 of '''SimpleTimer.h'''
  
 
==Troubleshooting==
 
==Troubleshooting==
Line 100: Line 114:
  
 
'Coz sumpin' borked yer compiler install...
 
'Coz sumpin' borked yer compiler install...
 +
 +
== Some Theory Discussion ==
 +
 +
=== About compiling & linking ===
 +
(A long winded response to a comment in a Discord channel...)
 +
 +
 +
"@Tinker's description isn't entirely accurate. "
 +
 +
 +
"The linker includes sections from a library that are referenced by other sections that are required. "
 +
 +
--
 +
 +
The linker is told at build time what libraries to use.
 +
 +
In general, the object code of a library is treated exactly like the object code of your program itself.  (This is why many Arduino libraries are so bad for bloating your final binary...)
 +
 +
<nowiki>=====</nowiki>
 +
 +
"Old compilers emitted one lump for each compilation unit (producing a .o file) and the linker would include all or none of a .o from inside a library."
 +
 +
--
 +
 +
New compilers also create one block of object code (.o file) per compilation unit.
 +
 +
<nowiki>=====</nowiki>
 +
 +
"Modern compilers break each compilation unit into many sections inside each .o file (like one per function, etc), and the linker is free to include only stuff that is referenced."
 +
 +
--
 +
 +
You may be thinking of dynamic linking.  In dynamic linking, the library is actually placed in a separate file by the linker & simply referenced from the main binary.  This is fine for programs running on a computer with storage & an OS.  (Doesn't work well on a microcontroller...)
 +
 +
<nowiki>=====</nowiki>
 +
 +
Typically "the programmer" wouldn't tell the linker what to include.
 +
 +
--
 +
 +
In a fully functional build environment (old-school "makefile" bases building or more modern IDEs...) the programmer always tells the linker what to include.  Many modern IDEs default a lot of this for you, but the process is still there.
 +
 +
<nowiki>=====</nowiki>
 +
 +
"The compiler that invokes the linker would include startup code (e.g. crt0.o) and that requires _main, which the requires more things that will be satisfied by other .o files or archive library files."
 +
 +
--
 +
 +
The compiler doesn't invoke the linker.  The linker is invoked AFTER the compiler (or multiple compilers) & acts on the object files created as output from the compiler.
 +
 +
<nowiki>=====</nowiki>
 +
 +
"Traditional *nix linkers make one pass through the list of libraries, not going back to an earlier library to get new things that may be required by a later one, so in some incestuous situations you had to include the same library more than once."
 +
 +
--
 +
 +
If you include the actual library more than once, your program will not work.  You may be thinking if the headers for the library (i.e.: `#include <library.h>`).  This is not including the library, it is including the definitions that the library uses.

Latest revision as of 13:43, 3 August 2021

Atom as a full IDE

bash

Dialogs

Some Links

C

C++

(Apparently, a language designed to make C programmers lose their minds...)

Converting numbers to strings

Problem Solving

  • Error] cannot pass objects of non-trivially-copyable type 'std::string {aka class std::basic_string<char>}' through '…'

Processing

JavaScript

Arduino (Language)

Data Type Conversions

char* to String

char *message = "Hello";
String myString = String(message);

String to char*

Messing about with strings & not Strings

http://www.cplusplus.com/reference/cstring/

Specifically: strcat

Memory Saving

PROGMEM

Some Libraries to Check Out

STUPID Library Compile Warnings!!!

Dear library writers,

Please fully debug your code before release.

It's not THAT difficult. Really.

I fully understand that compiler warnings do not indicate that your code will not work as expected, BUT, compiler warnings during a build are rather disconcerting.

Arduino Libraries

PubSubClient (2.8.0)

.pio/libdeps/SugarBush_SS_Climate_BME280/PubSubClient/src/PubSubClient.cpp: In member function 'boolean PubSubClient::publish_P(const char*, const uint8_t*, unsigned int, boolean)':

.pio/libdeps/SugarBush_SS_Climate_BME280/PubSubClient/src/PubSubClient.cpp:523:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

     return (rc == expectedLength);
                   ^

FIX: Add unsigned to the definition of expectedLength on line 487 of PubSubClient.cpp

SimpleTimer (0.0.0-alpha+sha.b30890b8f7)

.pio/libdeps/SugarBush_SS_Climate_BME280/SimpleTimer/SimpleTimer.cpp: In member function 'void SimpleTimer::run()':
 
.pio/libdeps/SugarBush_SS_Climate_BME280/SimpleTimer/SimpleTimer.cpp:66:60: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

if (current_millis - prev_millis[i] >= delays[i]) {
                                               ^

FIX: Add unsigned to the definition of delays[] on line 106 of SimpleTimer.h

Troubleshooting

When trying to compile things on a Linux machine...

You get silly-ass errors like fatal error: stdio.h: No such file or directory or other files missing that just don't make ANY sense...

  • sudo apt update
  • sudo apt install --reinstall build-essential

'Coz sumpin' borked yer compiler install...

Some Theory Discussion

About compiling & linking

(A long winded response to a comment in a Discord channel...)


"@Tinker's description isn't entirely accurate. "


"The linker includes sections from a library that are referenced by other sections that are required. "

--

The linker is told at build time what libraries to use.

In general, the object code of a library is treated exactly like the object code of your program itself.  (This is why many Arduino libraries are so bad for bloating your final binary...)

=====

"Old compilers emitted one lump for each compilation unit (producing a .o file) and the linker would include all or none of a .o from inside a library."

--

New compilers also create one block of object code (.o file) per compilation unit.

=====

"Modern compilers break each compilation unit into many sections inside each .o file (like one per function, etc), and the linker is free to include only stuff that is referenced."

--

You may be thinking of dynamic linking.  In dynamic linking, the library is actually placed in a separate file by the linker & simply referenced from the main binary.  This is fine for programs running on a computer with storage & an OS.  (Doesn't work well on a microcontroller...)

=====

Typically "the programmer" wouldn't tell the linker what to include.

--

In a fully functional build environment (old-school "makefile" bases building or more modern IDEs...) the programmer always tells the linker what to include.  Many modern IDEs default a lot of this for you, but the process is still there.

=====

"The compiler that invokes the linker would include startup code (e.g. crt0.o) and that requires _main, which the requires more things that will be satisfied by other .o files or archive library files."

--

The compiler doesn't invoke the linker.  The linker is invoked AFTER the compiler (or multiple compilers) & acts on the object files created as output from the compiler.

=====

"Traditional *nix linkers make one pass through the list of libraries, not going back to an earlier library to get new things that may be required by a later one, so in some incestuous situations you had to include the same library more than once."

--

If you include the actual library more than once, your program will not work.  You may be thinking if the headers for the library (i.e.: `#include <library.h>`).  This is not including the library, it is including the definitions that the library uses.