Тёмный

#BB9 

Ralph S Bacon
Подписаться 54 тыс.
Просмотров 16 тыс.
50% 1

Organised code is so much easier to read, debug and maintain.
► PCBWay $5 for 10 pieces www.pcbway.com
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." - Martin Fowler (en.wikiquote.org/wiki/Martin_...)
► Summary
I was taught early on in my computer programming career that beautiful code indicates a tidy, organised mind too - and probably leads to code that works first time, is easily understood by others and can be maintained in the years to come.
In this video we look at how we turn "prototyping code" into a well-structured, modular program by separating the various components of the program into separate files.
All the code in the video is available in the GitHub for you to play around with:
github.com/RalphBacon/BB9-Cod...
► Hardware used in demo project:
LCD screen INCL I2C backpack (ships from UK): www.banggood.com/custlink/Dmm...
Separate Backpack (for bare LCD screen): www.banggood.com/custlink/KmD...
DS18b20 temperature sensor (TEN pieces): s.click.aliexpress.com/e/_AYM61d
DS18b20 Waterproof version (1m cable): s.click.aliexpress.com/e/_9fiBAb
Pictures and more info in my GitHub: github.com/RalphBacon/BB9-Cod...
► Next Steps
The next video (BB10 in this series) progresses this theme and will cover namespaces - which goes some way towards getting rid of true globals. Grr!
Stay tuned!
► Useful or interesting video? You can support my channel:
Buy Me A Coffee! www.buymeacoffee.com/ralphbacon
► List of all my videos (Special thanks to Michael Kurt Vogel for compiling this)
bit.ly/RU-vidVideoList-RalphB...
► If you like this video please give it a thumbs up, share it and if you're not already subscribed please consider doing so and joining me on my Arduinite (and other μControllers) journey
My channel, GitHub and blog are here:
------------------------------------------------------------------
• / ralphbacon
• ralphbacon.blog
• github.com/RalphBacon
• buymeacoffee.com/ralphbacon
------------------------------------------------------------------

Наука

Опубликовано:

 

26 май 2022

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 179   
@Cptnbond
@Cptnbond 2 года назад
You are the master of all YT code and hardware teachers in the way you inspire and make it simple to understand - whatever topic you talk about. Cheers.
@RalphBacon
@RalphBacon 2 года назад
Thank you for your kinds words, most appreciated. I wonder if you will say the same after my video on Pointers? 😲
@Cptnbond
@Cptnbond 2 года назад
@@RalphBacon We will see. Lol.
@simonbaxter8001
@simonbaxter8001 2 года назад
It's not only easier to read and debug ... it also makes your code 'blocks' reusable in other projects without having to write portions of code again as you've essential created your own mini library for your projects!
@RalphBacon
@RalphBacon 2 года назад
That is so true and not something I consciously thought about - but I reuse blocks of my code from other projects all the time!
@N6ROB
@N6ROB Год назад
Just wanted to say that this video (and BB#10) has really helped me improve my code. As my program gets larger, and larger (with more features), this method of organizing code has really helped me to think more clearly about how it should be structured. I'm not especially good at it, and I struggle sometimes with moving variables from one place to another, but at least I am heading the right direction. I was even inspired enough to create a git hub page - yikes! This, from a guy who is more comfortable with a solder iron than a keyboard and compiler! Thanks Ralph.
@RalphBacon
@RalphBacon Год назад
This is excellent news, thanks for the update. Yes, software can be scary for hardware engineers but as my (development manager) boss used to tell us, "It's just typing". That upset a few people that day!
@jackdowning8841
@jackdowning8841 2 года назад
Probably one of the best code organisation videos I've every watched, cheers Ralph!
@RalphBacon
@RalphBacon 2 года назад
Great to hear! Now go and try it out or download my example sketch, Jack!
@jstro-hobbytech
@jstro-hobbytech 2 года назад
Very, very good video. You're raising up everyone who wants to learn. It makes code reusable too for other projects.
@RalphBacon
@RalphBacon 2 года назад
Glad you think so! Namespaces soon then!
@jstro-hobbytech
@jstro-hobbytech 2 года назад
@@RalphBacon I use std usually haha. I love pure c++. Even though I'm not a professional like you I'm familiar with most concepts but i dont code enough. Ive been very circuit oriented lately with the theory and breadboarding different concepts. I have so many breadboards that if its something i dont really understand fully they get placed on a shelf infront of me until they do. I have a few giant ones that you can put power in the jacks but i want one that has different built voltage supplies so you can have negative voltage rails. They are absurdly expensive so ill probably end up just making my own out of the new one i have that has over 16k tie points lol. I'm loving these videos Ralph so keep them coming. Do you have patreon?
@RalphBacon
@RalphBacon 2 года назад
I've just ordered two more breadboards as I keep leaving the circuits on them for too long whilst I think about a video! And I have some large ones too but frankly they are too big for most uses. Except my ESP32 Web Radio, that needed a big one. I don't have a Patreon but if you want to support me occasionally check out my video description or GitHub as I have a "Buy me a coffee" link which many of my supporters have used in the past. ☕
@joshlikessurfing
@joshlikessurfing 2 года назад
Glad you did it the "lazy way". I have always wanted to do more .h and .cpp file setup but it just felt like so much. This is a great stepping stone.
@RalphBacon
@RalphBacon 2 года назад
Glad it was helpful! Yes, splitting the header and code files is a right chore. And when there is no boss to say "do it!" then we don't have to!
@PeranMe
@PeranMe 2 года назад
Good job as always Ralph!
@RalphBacon
@RalphBacon 2 года назад
Thank you! Cheers!
@tseckwr3783
@tseckwr3783 2 года назад
thanks Ralph. it is always good to be organized in code.
@RalphBacon
@RalphBacon 2 года назад
Absolutely!
@200sxgrazor
@200sxgrazor 2 года назад
Many thanks for this, Ralph. I've just refactored my current project to use this organisation structure and it still works!!!! :) Looking forward to the next instalment.
@RalphBacon
@RalphBacon 2 года назад
Fantastic! But don't sound so surprised! 😁 Namespaces this Friday before I take a break!
@200sxgrazor
@200sxgrazor 2 года назад
@@RalphBacon I spoke too soon. I've tried taking it a bit further and attempted to make better use of functions but I'm now running into various scope issues :( but I should add these are self inflicted by bad coding practices. this confused me for a bit but I'm managing to sort them out :)
@TimSeymour
@TimSeymour Год назад
As a rank hobbyist, this was SOOOO helpful... my code was getting out of control as I kept adding more features to my project. I have reworked my sketch and have found that the order of declaring the #includes is important. So satisfying to clean house! THANK YOU
@RalphBacon
@RalphBacon Год назад
Glad it helped! 👍 Yes, the order of the #includes is important. Remember, too, that you can include other files into each of the individual header files (as long as you remember to put the #pragma once at the top. So a header file of definitions might be included in just about every other header file as well as the main sketch. But that's fine and ensures the compiler can "see" all the variables at compile time - but just the once!
@Roel_Scoot
@Roel_Scoot Год назад
I had since some time discovered the tabs for housekeeping larger programs, but did not know exactly how to implement them. Now I know, thank you!
@RalphBacon
@RalphBacon Год назад
Excellent! Now get organising your code, it will feel good!
@maxximumb
@maxximumb 2 года назад
Another excellent video.
@RalphBacon
@RalphBacon 2 года назад
Glad you enjoyed it!
@ChrisBalmforth
@ChrisBalmforth Год назад
I just discovered your channel this morning and it's perfect for me as a self-taught hobbyist robotics programmer. I want to use good practices but it's been difficult for me to find suitable tutorials. Keep the good stuff coming along!
@RalphBacon
@RalphBacon Год назад
Welcome aboard! Now watch the other 252 videos 😲😂
@ifell3
@ifell3 2 года назад
Wow this is great, never knew you could add tabs etc!
@RalphBacon
@RalphBacon 2 года назад
Glad you like it! And, yes, do try it out, it really makes a difference.
@stevex3976
@stevex3976 Год назад
Very interesting. This is something I have been looking for to clean up programs. Thanks!
@RalphBacon
@RalphBacon Год назад
You're welcome!
@arnotek
@arnotek Год назад
Thank you! I have been writing software for over half a century (egads - where did the time go?) and I am still learning. This is spot on - even for a hobbyist. Don't believe me? - then go back and look at something that you wrote 6 months ago. I have always subscribed to writing code so the person coming in behind me would understand what the code was doing, including lots of comments. The mantra of "the code is self-documenting" is very naive. I also like your comment of putting code in the .h file. (or .hpp) It is clean and concise and reduces unnecessary files that would add to the complexity of trying to keep everything straight. Yeah, the purist heads will explode - but I think it is the way to go. Thank you again for the effort you put into all of your videos. And yes, you can teach an old dog new tricks. :o)
@RalphBacon
@RalphBacon Год назад
Thanks, Arno. I've only been writing code (for a living) for about 42 years so well behind you. I've seen quite a sea-change of concepts in that time, all very exciting (at the time). These days, I tend to think "Micro Python on a Pi? Great." and just continue with my C++ work!
@Tony770jr
@Tony770jr 2 года назад
Another great video. I haven't thought too much of using the namespace feature in Arduino code, but makes things less ambiguous. Keep the videos coming!
@RalphBacon
@RalphBacon 2 года назад
Glad it was helpful! But we'll cover the namespace feature in more depth next video (in this series).
@espedito2003
@espedito2003 2 года назад
Excellent topic.
@RalphBacon
@RalphBacon 2 года назад
Thank you, glad you found it interesting.
@espedito2003
@espedito2003 2 года назад
@@RalphBacon Sure did! Greetings from Brazil.
@gordondyer6310
@gordondyer6310 2 года назад
I'm new(ish} to Arduino and have written a 1600 line program all in one .ino file! Thanks for the lesson, some day I will try to untangle my spaghetti into several files.
@RalphBacon
@RalphBacon 2 года назад
You can do it! Keep you busy, anyway!
@JulioSalim
@JulioSalim 2 года назад
You are the best!!! Thank you!!!
@RalphBacon
@RalphBacon 2 года назад
Wow! High praise indeed, Julio, thank you!
@RupertBruce
@RupertBruce 2 года назад
Essentially, you are using namespaces to group static functions instead of building classes, instantiating and hopefully destroying them. I like it! Minimal syntax and no memory leaks - great organizational tool for these projects. 😎
@RalphBacon
@RalphBacon 2 года назад
Hah! You said it! Classes are not easy for beginners (although they are using them all the time with all those library functions and objects!) But, yes, this starts making developers think about where all the code has to go. Separation of concerns and all that.
@markday3145
@markday3145 2 года назад
Your starting code was already quite well organized, making the benefits of the reorganization less apparent. What really made a difference there was the addition of a few wrappers/convenience functions. Those could have just as easily stayed in the one source file. For a project that small, breaking it up into multiple files is less critical. For bigger projects, breaking things up can be a huge improvement. I'm glad you're going to cover namespaces. They are great for organizing code and simplifying naming.
@RalphBacon
@RalphBacon 2 года назад
As I edited my video I realised I should have made the code starting point more typical of what I see! Mine was already far too tidy! Yes, namespaces are easy to understand and give useful benefits.
@MUHAMMADYAWARIFRAHEEM
@MUHAMMADYAWARIFRAHEEM 2 года назад
Very informative video Sir 👍
@RalphBacon
@RalphBacon 2 года назад
Glad you liked it!
@zeferby
@zeferby 2 года назад
Excellent video Ralph! Edit: having paged down further into the comments, I now see multiple references to the same traditionnal technique... :-) About the #pragma portability question : I more often use something "manual" like this in my various code and header files : Header file : #ifndef included_filename_symbol_h #define included_filename_symbol_h ... contents of header file here ... #endif included_filename_symbol_h Code file : #ifndef included_filename_symbol_h #include "included_filename.h" (or instead of "...", or hpp instead of h, depending on file location, etc...) #endif included_filename_symbol_h ... use header declarations in code ... NB: some compilers require the #endif to be written alone without the symbol name; I like my #endifs to have the related symbol name when possible to avoid confusion when I have a lot of #endifs one after the other...
@RalphBacon
@RalphBacon 2 года назад
Yes, I use #endif // __myDef_name__ to make it clear too.
@atilliator
@atilliator 2 года назад
perfect, just started doing this myself
@RalphBacon
@RalphBacon 2 года назад
Excellent! And you can use namespaces too to improve it, next video in the series!
@pfeerick
@pfeerick 2 года назад
Great video Ralph... And also damn you... now I got to go clean up some of my code! 😂😂 I use helper setupWifi(), setupOTA(), setupMQTT() etc but hadn't go to the extent of separate files or namespaces. btw, this isn't the first time I've seen header only implementation.... and I think I've even seen somewhere that it was more than "just being lazy"... that there was some compile efficiency reason to do it sometimes...
@berthold64
@berthold64 2 года назад
I'd suggest put those into .cpp with header declaration. Believe me, big header file with implementation can impact your compilation time. You'd be thankful knowing how cpp and h files link together. You may also learn static linking (.a/.lib) files too, it can be useful down the road.
@RalphBacon
@RalphBacon 2 года назад
The first step is always to stand up and say "Hi, I'm Ralph and I'm a ... messy coder". Then split your files as I have shown. Next video we'll talk about namespaces but it's more of an evolution than revolution to what we have here already. If you really want to do it 100% correct (as null says here) and split the header into .h and .cpp files then by all means do it, but IMHO it's a diminishing return on investment for hobbyists. Each file must have visibility of variables that it refers to or your IDE will barf, so you must include the necessary .h files as required - all with #pragma once, of course. Start small, as I showed, and work up from there. You know it's/we're worth it. 😜
@coxsj
@coxsj 2 года назад
+1 for Bacon bytes!! Love it!!
@RalphBacon
@RalphBacon 2 года назад
Yummy! 😋
@mr.bianchirider8126
@mr.bianchirider8126 2 года назад
One frustrating occurrence while coding is trying to find a particular line out of 500+ lines. By using tabs to compartmentalize ( hmm.. is that a word ?) the code, it will make it easier to debug. Thank you and please continue on this subject.
@RalphBacon
@RalphBacon 2 года назад
I'm glad you found it good food for thought. Next video in this series is about namespaces which goes a little further. You will find that equally interesting I should think.
@stevex3976
@stevex3976 Год назад
Hi Ralph, I used your video as a guide on a program I have been working on for a friend. It uses a Nano with a 2 x 16 LCD to read and display the position of a volume pedal on a guitar effects stomp box. User can select between 2 display types. I ended up with 2 function calls in the main loop! Thanks for the direction! void loop() { twoBar = CheckUserInput(twoBar); DisplayPedalPosition (twoBar); } // end loop
@RalphBacon
@RalphBacon Год назад
Fantastic! The more you use the technique the better it becomes.
@stevex3976
@stevex3976 Год назад
@@RalphBacon Now with namespace! void loop() { twoBar = UserIn_NS::CheckUserInput(twoBar); Math_NS::DisplayPedalPosition (twoBar); } // end loop
@steverileyretired
@steverileyretired 2 года назад
Good idea
@RalphBacon
@RalphBacon 2 года назад
Many thanks! Now go and try it, Steve, with some simple project you've previously written. It really makes a huge difference the more you do it this way.
@andymouse
@andymouse 2 года назад
Interesting stuff, I need to be tidier !...cheers.
@RalphBacon
@RalphBacon 2 года назад
You do Andy, and so does your code. 😉
@andymouse
@andymouse 2 года назад
@@RalphBacon Owch !!🤣...cheers !
@johnstephenson2891
@johnstephenson2891 2 года назад
My software development company in California had about 18 programmers(?). Maybe half wrote clear understandable code! I gave them two options, 1) re-write the code so it read like a book! or write two lines of comments per line of code!!!
@RalphBacon
@RalphBacon 2 года назад
Yes, a few comments can be very useful to the next programmer who has to maintain that code (probably yourself). The problem with comments is that they might just describe WHAT the code does rather than WHY or HOW. For example (made up example): // Set the engine's intermix ratio bool success = (setInterMixCoolerRatio(14.983 * &WarpEngineFactor / AntiMatterRatio)^MaxSpeed) % 50; That comment tells you nothing that could not be gleaned from reading the code. What's missing is how it's doing it and why, amongst other things, it's using the magic number 14.983 (just as an example, because everyone knows that's the accepted conversion factor for all anti-matter engines). 😜
@haraldh.9354
@haraldh.9354 2 года назад
good work -thx
@RalphBacon
@RalphBacon 2 года назад
No problem 👍
@1over137
@1over137 Год назад
Tip. If you are using a ds1820 temp sensor in it's "waterproof" capsule. It's not waterproof! The capsule has a bit of sticky snot in it, the sensor is stuffed in and the heatshrink applied. If you want to use it outdoors always mount it so the silver capsule it pointed upwards to allow condensation to drain out. Other wise after about 6 months to a year it will eventually fill with water, the glue will degrade and it will stop working. Mine worked again for a few days after I dried it out, but then it became intermittent and I had to replace it.
@RalphBacon
@RalphBacon Год назад
Good pointer, Paul. I've also found that if the heat shrink is removed (it's not totally watertight) and replaced with adhesive heat shrink (normally shrinks to 3:1 ratio too) then it's fine.
@webslinger2011
@webslinger2011 2 года назад
Simple but very useful for beginners like me. Been fooling around with 3d printer Marlin firmware wondering how it’s all setup.
@RalphBacon
@RalphBacon 2 года назад
Glad it was helpful! Marlin firmware? good luck with that!
@joshlikessurfing
@joshlikessurfing 2 года назад
Best tools for Marlin are configuration file, marlin main file and control f. If you use vs code you can track down references to functions. Think sublime text does this as well.
@NigelAtkinson256
@NigelAtkinson256 2 года назад
I've worked with "header only" libraries in the world of big computers, with all their code in headers or even just one header. While making separate cpp files might seem more "proper" I see no reason to complicate things. However if you're project is really getting bigger then that will help. One benifit of separate cpp files is that if you don't change the code, they don't need re-compiling which is great if they are really getting on the bigger side or you have a lot of them. That way only the file(s) you changed since last compile need compiling.
@RalphBacon
@RalphBacon 2 года назад
Only the purists will really complain about header-only code! Your Real World experience shows that it still works. 👍🏻
@willofirony
@willofirony 2 года назад
When I start a project I tend to use a python script to generate the file(s). Each file has the boilerplate code (I still use the old fashioned include guards rather than the once pragma) , common includes etc. The organisation of the body of the code is "suggested" by a series of comments as is the more optional includes (less common includes can be 'included' by arguments to the script). I do this for desktop projects and embedded projects (there are a number of scripts for each environment). I find this reduces errors (Ok it also panders to my laziness too). More importantly the "suggested" structure of the code imparts a discipline that aids debugging appreciably. Without getting too arty farty , writing code is a creative process (albeit riddled with plagiarisms). Most often this is done away from the keyboard, on the way to work etc. So, when the opportunity to commit these ideas to written code presents itself, it is accompanied by some impatience. One wants to get that algorithm that will revolutionise the software industry on the disk before it disappears like those plans for the flying car did. So having a disciplined approach to getting that into the memory of a computer at least suggested can result in a working prototype. With desktop projects the scripts can be more elaborate, decorating the files with keywords (commented) that can be used later by yet another script to generate a cmakelists.txt file for the build. I am enjoying this series of tutorials immensely, Ralph. Well done you!
@RalphBacon
@RalphBacon 2 года назад
You are very organised and disciplined, Michael. Except for the bit about the flying car designs 😜, of course. 'Nuff said. At work we occasionally had a 'sprint' where we refactored the code - it really made a difference to the overall quality and allowed us time to do the things we'd wish we'd done first time around (if we'd had the time! - Yes, I see the irony). Anyway, I'm glad you're enjoying the videos!
@TheOleHermit
@TheOleHermit 8 месяцев назад
Thank you so much for covering these 'tips of the trade', Ralph. You described me to the 'T' as being a self-taught, untrained coder. I've learned 95% of what I know from YT tutorials, like yours, but have never seen anyone else covering these finer details, like passing references to memory. My current project is a MIDI controlled Teensy 4.1 laser synth, with ~1500 lines of code in my Arduino sketch... so far. I've only just come to the point of learning how to create my own much needed custom libraries. "Necessity is the mother of invention." This video greatly simplifies how to get from A>B>C++. Excellent series of shorts. 👍
@RalphBacon
@RalphBacon 8 месяцев назад
Glad its helped you make your code sleeker!
@IanSlothieRolfe
@IanSlothieRolfe 2 года назад
Just to add my usual 10p ramblings, I would use # defines to define pin numbers for hardware connections and address settings etc and put them in the globals.h rather than scattering them around in the helper files - this will make porting the code to a different microcontroller board (e.g from an Arduino to an ESP32) much cleaner, you'd just have to update the globals.h file. Since these definitions do not relate to a namespace (i.e. they are constant across the whole project by definition) then putting them in a namespace may be arbitrary and make them hard to find in a complex projecct.
@RalphBacon
@RalphBacon 2 года назад
It's six of one and half-a-dozen of the other in my mind. Sometimes I do it the way you suggest, sometimes I put the #defines in the helper file to which they pertain. In the end it makes no difference, of course, but grouping the not-quite globals together is probably the better way of doing it. Using constexpr instead of #define also allows the compiler to be efficient but then we can also use namespaces (next video!).
@byronwatkins2565
@byronwatkins2565 2 года назад
If your compiler (pre-processor) doesn't recognize #pragma once, you can use 'include guards' instead: #if !defined (UNIQUE_H) #define UNIQUE_H /* Your code here. */ #endif // UNIQUE_H You typically use your header file name as your unique constant. Managing this yourself, you risk complications like another piece of code using the same constant, forgetting one of the three lines, typo, interactions with other #if constructs, etc. If possible, #pragma once is much more robust and convenient; so, use include guards as Plan B.
@RalphBacon
@RalphBacon 2 года назад
Indeed, that's the bit I said "I won't go into that now!". For beginners, include guards are clunky and beginners forget the #endif at the end! "#pragma once" is easily understood and all _modern_ compilers accept it, just the legacy ones not.
@whitefields5595
@whitefields5595 4 месяца назад
Another benefit of this approach is that once something is working in a separate tab you can leave it alone. If its all the the same place you can make unintentional silly mistakes that take ages to find
@RalphBacon
@RalphBacon 4 месяца назад
Absolutely. Combine the separate tabs approach with namespaces and the "silly mistakes" that you mention (we've all done it) simply cannot be unintentionally made.
@awuk3468
@awuk3468 2 года назад
Many "professional" environments are "fair game" to source code obfuscatory practices, many monolithic single .c/cpp file to run an entire system. :: is the scope resolution operator, which means you can access namespaces etc using it. Typically header files are for declaration and associated c/cpp files are for implementation but you can write everything in the header file, it works the same mainly convention, some libraries are just a .h file. #pragma once is a replacement for the legacy header include guard (#ifndef _XXXX_H #define _XXXX_H ... #endif), you can use both, most modern compilers support the #pragma once but some legacy code which require certain older compilers may not recognise it.
@RalphBacon
@RalphBacon 2 года назад
Talking of "obfuscatory practices" I've seen a few files full of hex that is actually code to be executed. So much for "Open Source" in some cases 😬
@awuk3468
@awuk3468 2 года назад
@@RalphBacon Unfortunately some think "open source" is supplying the HEX / firmware file, so I guess supplying a source file with the hex code inside is the next evolution of that. Although what a lot seem to forget is that anything that can be compiled can be decompiled, just takes a bit more time.
@RalphBacon
@RalphBacon 2 года назад
Indeed. In one case I found an online "decompiler". The "encrypted" source was in hex but it was standard source code, not compiled. Ascii, basically. So it was more a case of code obfuscation than just supplying the compiled code.
@yogeshitaliya473
@yogeshitaliya473 2 года назад
😍😍😍
@RalphBacon
@RalphBacon 2 года назад
I don't know how you are always the first, Yogesh. well done 👍🏻
@yogeshitaliya473
@yogeshitaliya473 2 года назад
@@RalphBacon respect sir Your all video 😅😍😍😍
@markvreeken
@markvreeken Год назад
Question ; My standard library files don't include #pragma once . Is this just sloppy programming or ????
@RalphBacon
@RalphBacon Год назад
They might include the more "traditional" way of preventing multiple inclusion by using something like: #ifndef __SOME_NAME #define __SOME_NAME all the library stuff in here #endif But "#pragma once" is the new, improved, time-saving way of doing it. One or the other should be present, otherwise it is, indeed, sloppy coding! 😁
@gregorymccoy6797
@gregorymccoy6797 2 года назад
Good practices. Gosh if only some of the libraries were as well-written. We have rigid style practices and project layout at work for code and some of them are senseless... But at least we have them 🙂.
@RalphBacon
@RalphBacon 2 года назад
So true!
@BerndFelsche
@BerndFelsche 2 года назад
It also makes code easier to reuse in realtime threads. Well, when you name it as code instead of header. 😜
@RalphBacon
@RalphBacon 2 года назад
Hehe! Yes, I thought you might object. 🙄 I knew some developers would object to using header files for code, hence my brief explanation in the video that for hobbyists it's probably "good enough" and allows beginners to understand the concept of code modularisation without the added complexity of multiple headers and multiple matching cpp files. It can easily overwhelm a beginner who is trying to separate concerns and adhere to the single responsibility principle. But if you want to do it 100% correctly, we should indeed put executable code into cpp files and only declarations into header files. 😉
@g0hjq
@g0hjq 2 года назад
@@RalphBacon I've seen massive Linux libraries written purely in .h files. I suppose they must have their reasons.
@Hangs4Fun
@Hangs4Fun 6 месяцев назад
question, at 13:46 you show using the printf function in your lcdHelper.h file, but you don't have any reference to the printf library at the top of that file. Is the compiler finding the function somewhere through the daisy chaining of includes and such? Great video's btw :-)
@Hangs4Fun
@Hangs4Fun 6 месяцев назад
and as I watch further in, at 14:36 I see the LibPrintf.h include in the globals.h file... I remember that from one of your earlier video's, just didn't know the includes worked that way, thanks.
@RalphBacon
@RalphBacon 6 месяцев назад
In this case, including a library at a high level ensures other parts of the code can find it (if those files are included too). So, yes, one reference to the library is enough, which I often put in the globals.h if it is a "general" library (ie used by lots of sketch files) and globals is then included in other files.
@Hangs4Fun
@Hangs4Fun 6 месяцев назад
@@RalphBacon thanks, much appreciated..
@livetohash6152
@livetohash6152 3 месяца назад
​@@RalphBacon... Again with a Q that I could test, but would it be good to put your compile directives in a global.h file for easy reuse? Like #define debugln(x) Serial.println(x) and others? Then you can erase them to save space later🤞
@aleksanderklimczyk7879
@aleksanderklimczyk7879 2 года назад
How would you replace: String newStr = str1 + str2 + str3; To make it use less memory and combine all the strings into one at once?
@jimbarchuk
@jimbarchuk 2 года назад
In globals you define various variables and defaults. In sensors add code to read into variables, or other code to create them. I don't recall exactly what the details of LCD code here was, so what I describe is generic... After all mainline functions are done, there's an 'end of loop' function to concatenate all the variables. Then LCD prints just one variable.
@RalphBacon
@RalphBacon 2 года назад
@Aleksander I try to avoid the String type (capital S) and use the std::string type but that is probably only available on the ESP32. In the Arduino, one way of concatenating Strings 'efficiently' is to do something like this: String a = F("Hello "); String b = F("World"); String c = "!"; a.concat(b.concat(c)); And so on.
@livetohash6152
@livetohash6152 3 месяца назад
I'm curious, if you use nice names in your code, could you compress that for deployment? Like instead of pirForward pirWest and pirBackyard... Do #define pirForward p1... Etc... Would this help save space? .. I could just test it, but curious your thoughts 🤔
@RalphBacon
@RalphBacon 3 месяца назад
If you had a variable called 'my_Exteremely_Long_Name' and another sketch with a variable called 'x' which would compile to the smallest code? The answer is that they would both compile to the same size, because variable names are ONLY used at compile time, not at run-time (ie post compile/link stages). Just in case someone jumps in to correct me, if you compile in debug mode (rather than release mode), yes the long names are retained for debugging purposes (how else would you reference a compiler variable name of y21?). But in general terms, variable names do NOT increase code size. You can try this for yourself pretty easily!
@livetohash6152
@livetohash6152 3 месяца назад
@@RalphBacon thanks, you rock 💯👍
@fillempie1501
@fillempie1501 2 года назад
Why do you put all the sourcecode in the *Helper.h" file? It is more common to place the function-interface (name of the function and parameters) in the .h file and the sourcecode in the cpp.file. Also after you changed the cpp file the whole project does not need to recompile....
@RalphBacon
@RalphBacon 2 года назад
Hmm, I knew some developers would object to this, hence my brief explanation in the video that for hobbyists it's probably "good enough" and allows beginners to understand the concept of code modularisation without the added complexity of multiple headers and multiple matching cpp files. It can easily overwhelm a beginner who is trying to separate concerns and adhere to the single responsibility principle. But if you want to do it 100% correctly, we should indeed put executable code into cpp files and only declarations into header files.
@jcxtra
@jcxtra 2 года назад
Small comment this week (I think, at least that's my intention!) Could you do a video on how to setup VS Code to do arduino projects? I like some of the ways that VSCode works but the guides I've seen online haven't been easy to follow. I started using an IDE for a Tcl project I worked on (Komodo since it can do contextual things as it understands the language and has links to git) and I think I'd like to set that up since eventually other people are gonna have to be able to work with my code too, so that'd be a nice video, if you wouldn't mind ^^, Pretty pweese? (After you've done pointers and structs :p) x
@RalphBacon
@RalphBacon 2 года назад
Demanding or what? 😁 Actually, the new Arduino 2.0 IDE has the potential to be really good although whether it becomes as good as VS (PlatformIO) time will tell. I'll wait for the final release of the Arduino IDE first before committing to a VS video as it's going to open up Pandora's box, I just know it is.
@bryansmith1303
@bryansmith1303 Год назад
All your videos help me be a better programmer. In the download file, in the sensor helper file. In the code copied here:// Read sensor float getTemperature() { sensor.requestTemperatures(); Serial.println("Requesting temp"); while (!sensor.isConversionComplete()) ; a++; // Get temperature (float) return sensor.getTempC(); } You are using a++; I can't fine where is it declared and what is it used for. Could you explain?
@RalphBacon
@RalphBacon Год назад
This is odd, Bryan.🤷 Not only do I not know what that is doing there, I would almost never use a silly variable name like "a". Delete that line and pretend it never happened. I'll try and update the GitHub file too. Have I been hacked?
@PhilipHawthorne
@PhilipHawthorne Год назад
Hi Ralph. I've been using multiple files for some time in large projects but in some of the files I gave the .ino extension and some are .h. It seems to work ok but is this bad practice to use .ino? I have to #include the .h files but not the .ino. I assume the Arduino IDE is doing some work in the background?
@RalphBacon
@RalphBacon Год назад
Well... if it works for you🤷... But seriously, that's not exactly _standard_ naming practice. Headers (definition etc, no code) should have the ".h" extension, code (C++) should have the ".cpp" extension and if you do everything in the one file it should have the ".hpp" extension. But I break my own rules so... back to my first sentence! 😉
@PhilipHawthorne
@PhilipHawthorne Год назад
@@RalphBacon Thanks Ralph. I haven't been able to get PlatformIO working in Visual Studio Code properly so I'm using the new Arduino IDE 2.0.1. I do tend to put definitions of constants etc in .h files and the .ino files contain the code. Does the new IDE accept .cpp files? They're the same thing really, I suppose! As it's working, I will probably leave well-enough alone 😊😁
@RalphBacon
@RalphBacon Год назад
If it ain't broke, don't fix it! 😂
@PhilipHawthorne
@PhilipHawthorne Год назад
@@RalphBacon Yes, as my Dad used to tell me 😂
@1over137
@1over137 Год назад
@@PhilipHawthorne The INO files are the input for the Arduino IDE's pre-processor that adds all the scary code they don't want newbies to see. Also they don't want newbies to suffer from the frustrating fact that C++ is picky about the order of definitions and usage. If you define a function at the bottom of the CPP file, you can't call it in the functions above. For that you need to either move it to a header (exported variables for other modules to see) or a forward declaration at the top of the file. If you wanted to move away from the Arduino IDE, your first task will be to convert your INO files to actual CPP files. It's not hard, but you will start to face a few more elements of C++'s fussiness and somewhat frustrating error texts.
@jeffbluejets2626
@jeffbluejets2626 2 года назад
Hi Ralph, Think I saw something about that "read only once" written as an ifdef ....??? no...?? found the library upgrade problem also myself in the past. Some code writers will have a particular library included in the code. One can see it in the extra tabs which I thought a good idea. Maybe, instead of updating libraries, they should simply add a newer version, leaving the older versions in place with particular version number referenced in ones code. Had pc hdd die a couple of months ago and since found out, due to new install of IDE required, all my libraries have reverted to the "basic" as IDE installed. A right PIA as even the LCD library you refer to, I had to chase up and install. Then naturally check against some of my older code to see if it stll works. Bound to be some that will catch me out again in the future.
@RalphBacon
@RalphBacon 2 года назад
That's just one reason why I use VS PlatformIO; you can add libraries to the project and they will _never_ get updated. Just the way I like it. If you _do_ want libraries to update to a specific version then it will do that too, of course.
@ChristianSchmid
@ChristianSchmid 2 года назад
Maybe a gel like from LEE filters over jour display may increase the contrast significantly.
@RalphBacon
@RalphBacon 2 года назад
Good idea. I have a whole booklet of swatches from them somewhere... that's the problem. 😢
@geoffpanchaud967
@geoffpanchaud967 2 года назад
I use Quality street wrappers as coloured filters! The wrinkles hardly notice in practice.
@RalphBacon
@RalphBacon 2 года назад
I've done that! Really! The purple ones really work well! Warm them in hot water to take out the crinkles.
@zyghom
@zyghom 2 года назад
nice usb cable from the well known product ;-)
@RalphBacon
@RalphBacon 2 года назад
I can't remember where that yellow (and very flat) USB lead came from. Probably some audio product? But it is very durable and I keep using it!
@zyghom
@zyghom 2 года назад
@@RalphBacon Ultimate Ears Boom Bluetooth Speaker
@RalphBacon
@RalphBacon 2 года назад
Oh yes, the one I gave away to my daughter who now refuses to return it. I remember. 😢
@zyghom
@zyghom 2 года назад
@@RalphBacon I am not surprised - I ended up with 4 in my house - everybody loves them!
@maduromaduro9826
@maduromaduro9826 Год назад
creating many files is not a kind of "overhead" ? I am asking for high performance computing not embedded
@RalphBacon
@RalphBacon Год назад
There is _zero_ overhead in creating many files. The compiler will always create a single file containing all the referenced files (including libraries) and then compile.
@1over137
@1over137 Год назад
The rant around 13mins. At times I have agreed. However. The pain it will cause you later is far too great and far too much hassle to clean up. So I would advice at least learning/showing how to do it properly. Because "header only" C++ files have to be done very, very carefully or they will bite you. In your example, the instant you need to include the LCD header into more than one place your code will fail due to multiple definitions (and allocations) for LiquidCrystal_I2C lcd() object. Note "#pragma once" means once PER file. If you have a.cpp and b.cpp and both include your lcd header, BOOM! If you want header only C++ files YOU CANNOT HAVE GLOBALS in it. You either have to move your allocation declarations to the parent CPP file, create an actual hpp/cpp pair or you can wrap the allocation inside the class and allow it to allocate it's own memory dynamically (so it's not global).
@RalphBacon
@RalphBacon Год назад
There does need to be some severe structure to header files: what's in this, what files _they_ include, and what variables they need. I put globals into a separate file (usually). Mostly with a namespace. That way it can be included wherever it's needed and won't be included twice, even if header "a" includes it as does header "b". I've recently started to use ".hpp" files, purely because it's Best Practice. Makes no difference to the compiler or anything else. C++ lets you hang yourself if that's what you want to do!
@josip1881
@josip1881 2 года назад
Did you try to use Rust? :) Much easier to organize, but lacks some libs, nothing too bad.
@RalphBacon
@RalphBacon 2 года назад
I've not used Rust, although I hear it's good for embedded processors. In case others want to find out more, here's the link: www.rust-lang.org/
@ianbertenshaw4350
@ianbertenshaw4350 2 года назад
This is really something that you do with bigger programmes , newcomers need to understand that the simple programme you showed isn't something you would be bothered with .Handy to know how to do it for sure but for something less than say a hundred lines of code probably not worth it .
@RalphBacon
@RalphBacon 2 года назад
As I said, Ian, projects tend to ☘ grow. If your code is a mess before it starts to expand, well... you've got a problem! A small program like this probably doesn't need the full treatment but it's a good place to start (and practice).
@zyghom
@zyghom 2 года назад
if you included globals.h in the main file, then calling it again in lcdhelper file has no meaning (considering pragma once), right? with regards to have functions in h files: some libraries - even huge ones - are completely in h files - see i.e. ArduinoJSON library: "ArduinoJson is a header-only library, meaning that all the code is in the headers."
@RalphBacon
@RalphBacon 2 года назад
Including the globals.h in more than one file allows the IDE to be satisfied that each file can access stuff in the globals.h (whilst you are developing) but it will not include the file more than once during compilation as that would introduce duplicates, of course, just as you have understood. I never knew that some libraries were written with just a header file. I guess they were too busy to split it out!
@zyghom
@zyghom 2 года назад
@@RalphBacon if I am not mistaken (I might be of course) the code can be in txt or csv files - it is just a matter of convention, right? also splitting function declaration and function definition: as long as declaration is before definition... but what do I know ;-)
@RalphBacon
@RalphBacon 2 года назад
I've never tried to #include a .csv file! Perhaps it would work, but it would be very 🙄confusing. Best to stick with convention in this case, Zygfryd! Yes, declarations must come before definition but if your definition is written in a file before that you #include elsewhere then you don't need to (forward) declare anything.
@zyghom
@zyghom 2 года назад
For my home projects I have built a library where most of the functions are in separate files, i.e. wifi.h, pwm.h, mqtt.h etc. This way, by using #define in the main file and then #ifdef in the further ones, I can include some modules in the project, depending on what is the device for. I.e. if the device is to use SHT31 humidity/temperature sensor, I use #define USE_SHT31 and then all is done. The idea was to avoid rewriting the projects from the scratch but also, whenever I improve/change my code, I make a change in 1 file only (i.e. I recently changed wifi function to use fixed channel) - this way I change 1 file only and perform recompilation of all my devices (recently 50+ esp32 devices in my home) and the OTA to all of them (btw I made OTA from web so just 1 press on the home assistant screen to update them all at once). I wish I could find the way of re-compiling 50 projects at once instead of opening all 50 in Arduino... Maybe one day I will to to platformio but not yet.
@zyghom
@zyghom 2 года назад
... and I just keep 1 config file per device i.e. configure.h where there are device specific settings, i.e. the name or fixed IP address etc.
@sledgex9
@sledgex9 2 года назад
Also, maybe, instead of "#define ONE_WIRE_BUS 8" do either "static constexpr uint8_t ONE_WIRE_BUS = 8;" or put into an anonymous namespace like so: namespace { constexpr uint8_t ONE_WIRE_BUS = 8; } Both of those restrict the scope of ONE_WIRE_BUS to that particular file and provide type safety. Modern compilers will optimize away the variable.
@RalphBacon
@RalphBacon 2 года назад
Yes, that is a good way to do it too. From a compiler viewpoint I don't think it makes any difference whether we use a #define literal or a constexpr but either way is fine for me.
@jstro-hobbytech
@jstro-hobbytech Год назад
Ralph I wonder if there's a place for the 1 line either or expressions based on a condition like. Ralph ? Awesome : supercool; I forget what it's called haha. Most things we do I find can be broken down into pure boolean/bitwise operators to return a value that can trigger related logic or just keep on boogying through the code haha. By bitwise I don't mean the shifting unless you set up an 8 bit counter that decrements or otherwise every second check. Like when we go some stupid sensor to check
@RalphBacon
@RalphBacon Год назад
I love that ternary expression, Joey!
@jstro-hobbytech
@jstro-hobbytech Год назад
@@RalphBacon I cracked myself up when I was typing it hahaha
@jstro-hobbytech
@jstro-hobbytech Год назад
@Ralph S Bacon I've become a member haha. I thought I already was. My apologies
@ipadize
@ipadize Год назад
3:15 that text me: if if if if if programmer: Thats literally unreadable! me: i can read that perfectly 🤷‍♂
@RalphBacon
@RalphBacon Год назад
If I put my glasses on I can read more things, for sure!
@TheEmbeddedHobbyist
@TheEmbeddedHobbyist 2 года назад
Noooooooooooooooo, Headers are interfaces to the the code. No code in the header files please. 🙂 Sorry just had to say that, so when pep's look at headers and find there is no code they might look for files with the same name but diffent extension. As you say .cpp I'm just old school. well old and left schol a long time ago 🙂
@RalphBacon
@RalphBacon 2 года назад
Old school is not a bad thing. At work we would have to do the "right way", of course. I knew some developers would object to this, hence my brief explanation in the video that for hobbyists it's probably "good enough" and allows beginners to understand the concept of code modularisation without the added complexity of multiple headers and multiple matching cpp files. It can easily overwhelm a beginner who is trying to separate concerns and adhere to the single responsibility principle. But if you want to do it 100% correctly, we should indeed put executable code into cpp files and only declarations into header files.
@markday3145
@markday3145 2 года назад
No code in header files... unless you need/want to inline something. 😉 For a small hobby project, being written by someone who isn't a professional programmer, putting project-specific code (wrappers, convenience functions) in a header file isn't THAT bad. You're just splitting up that one big monolithic source file into a few files to make finding things later a little easier. Because of the way the Arduino IDE (or PlatformIO) works as a build system, they have to be header files, not .cpp files. If the code is more general, and you want to be able to reuse it later (even from multiple source files in the same project), then putting declarations in a header file and definitions/implementation into a source file makes more sense. You can always do that if/when you get to the point of wanting to reuse the code. Having used other languages that don't separate declarations, the C/C++ way starts to feel cumbersome and error prone. The one big advantage of the C/C++ way is that you can distribute precompiled libraries without source, in a way that is compatible with just about any compiler (as long as they understand the object file format, and can use the same ABI).
@peut
@peut 2 года назад
You can just add tabs and call the file .ino. Arduino will 'glue' them together at compile time. No need to include them and no code in .h files.
@RalphBacon
@RalphBacon 2 года назад
But if you don't #include them, then the declarations are not visible to the IDE for other programs to refer to?
@peut
@peut 2 года назад
@@RalphBaconthey are visible, as Arduino concatenates all .ino files before the compile (apparently)
@Tanuki5
@Tanuki5 Год назад
what about a .hpp file?
@RalphBacon
@RalphBacon Год назад
Interesting you should bring that up. Certainly, from a pure "C" perspective there is no indication with a ".h" file that the contents are "C" or "C++" whereas ".hpp" unambiguously states this is a C++ header (with or without code). Up to you whether you want to follow this methodology (Boost uses it) and it might makes things clearer to C programmers but C++ programmers might feel they don't need it.
@robertmurphree7210
@robertmurphree7210 Год назад
as retired C programmer, I didn't want to do any fancy C/C++ macro, or class stuff as an arduino hobbyist, afraid it would cause problems in arduino compiler. Introducing multiple files and hiding detail to hobbyist is great, I like just using .H files instead of .h + .cpp for hobbyist. and use of namespace to hide detail in multiple files suits hobbyist much better compared with lots of other C++ fine grained object oriented features. Enjoy your video's. great Teacher once told me his philosophy was to make things so easy people are comfortable enough and can use them as tool for life. Robert Murphree, retired state of Oklahoma programmer.
@RalphBacon
@RalphBacon Год назад
Great to hear from you Robert! Old programmers never retire, they just decompile 😟😲😉😁
@stephenbarlin2314
@stephenbarlin2314 Год назад
I tried this and just ended up with unfathomable scoping problems.
@RalphBacon
@RalphBacon Год назад
Remember you must refer to each function and variable in a namespace by its namespace followed by two colons. Eg myNs::myFunction();
@browaruspierogus2182
@browaruspierogus2182 2 года назад
good programmers don't use Arduino framework lol
@RalphBacon
@RalphBacon 2 года назад
Beginner programmers do, though. 😜
Далее
PORTAL SPAMMER🤬🤬🤬| Doge Gaming
00:19
Просмотров 1 млн
Викторина от ПАПЫ 🆘 | WICSUR #shorts
00:56
Наташа Кампуш. 3096 дней в плену.
00:58
#BB4 MOSFETs - From an Arduino Perspective
15:10
Просмотров 22 тыс.
All Rust string types explained
22:13
Просмотров 158 тыс.
451 Which Processor can kill the ESP32?
11:24
Просмотров 342 тыс.
Where Does Bad Code Come From?
42:21
Просмотров 188 тыс.
КРУТОЙ ТЕЛЕФОН
0:16
Просмотров 7 млн
АЙФОН Г0ВН0
0:54
Просмотров 1,8 млн