Hi there, first time posting to the forums, I apologize if this is not in the right location.
I have a prototype project I'm working on, for reasons that aren't really relevant or important, right now I need to do this via Arduino, and I am running into some bugs and things just acting strangely.
I am experienced with embedded c, avr-gcc, avr libc, gnu tools, in circuit debuggers, actual IDEs, all that, so dealing with arduino has been frustrating for me but I don't have time or resources to do things my way at the moment, so I've gotten up to speed on the way Arduino seems to want to work. All guides on Arduino are written for novices and not people trying to set compiler options or disassemble their code or who have access to a debugger. In any case...
my problem is I'm running into issues trying to command three independently controlled digital outputs, and 3 independently controlled PWM outputs. Sometimes the code acts differently say when compiled and run from one computer to another, or if some debug statement is added or removed
could this be some -O setting? does the Arduino have some quirk about how it stores flashed program memory?
I'm also seeing some of the pwm outputs behaving differently even though they should be using the same code and are each separately instantiated objects, no static shared members of the class. I don't know what's going on here
is there more like an expert's guide to Arduino that explains possible quirks? Why do they wrap the main file in an .ino file? are there better ways to debug this thing? I've been fighting with it for months now and I'm tired of having to try to break it just to get it to do things I know it should. Is there anything that explains all their strange design decisions?
First thing is read the pinned post re 'How to get the most from the forum'
Arduino IDE is specifically designed for Novice users. You could use VSCode instead, but the source code does NOT change. I have yet to use a debugger with the IDE or with any of my dozens of different supported boards, the sketches are too small and simple.
Forget the -O setting, concentrate on getting the sketch to work. You can try to optimize it later
You know more than me but why can't you use the complier of your choice (or assembly language) and simply re-map the I/O pins?
I assume the bootloader won't work but that shouldn't be a problem for you.
On the Uno, different pins do have different default PWM frequencies. I couldn't find the "real reference" in a quick-search, but it gave me an AI answer:
I am curious about why you “need to do this via Arduino.” If it’s because you have an Arduino board, all you need to do is treat it as any other breakout board for the MCU you are working with, and program it with tools and processes you are already an expert at using, then you’ll have no pain. For example, if you’re working with an Uno R3 board having an ATmega328P on it, write your program avoiding the use of anything Arudino-related, and program the ATmega328P chip using your tools, and enjoy. The only thing Arduino related you might find handy is the Uno schematic so you can tell which IC pin numbers go to which breakout board (Uno) pin numbers.
The experts guide is the datasheet for the microcontroller being used. The Arduino environment does not prevent you from programming it as described therein.
This is often a timing issue. Serial prints are very slow and can act as a delay in your program.
You will have to be more specific about your individual issues for additional help.
Things that Arudino does to make things easier for beginners:
define main to be effectively: setup(); for (;;) loop();
not "wrapping"; just plain old linking to find functions in another module
in the process of making your board Arduino-compatible, a lot of stuff can be done behind the scenes. For example, ESP32 stands up FreeRTOS and a main task for setup & loop, and in that loop-loop, it does a few other periodic things.
allow sources to be in one or more .ino files
glued together into a single .ino.cpp
#include <Arduino.h> is added automatically at the top, with a bunch of "handy" stuff
forward declarations are inserted so that function order does not matter
library detection, choosing the "best" one for every #include
Enable Verbose output in Settings, to show the build commands. You can see the location of the temp directory tree used for building, the .ino.cpp; all the libraries chosen, all the compiler switches. The builds use standard tooling.
If you've been at it for months, you may have figured all this out. Perhaps you can be more specific about the design decisions in question.
Variation in behavior from different programming environments is usually caused by different library versions.
You could use VS Code and Platformio which provides more control over the environment.
Or you can program an arduino board without the ide. Download Atmel Studio or whatever Microchip has renamed it and you can use a real in circuit programmer and debugger.
The Arduino documentation is intended mainly for beginners. Experts can look at the source code. Experts can also eliminate a lot of the possibly "unexpected" configuration and use of system resources such as timers etc. by using their own main() function instead of the supplied one.
I'm curious to see the specification (and code) of what would seem a straightforward Arduino project that has given an experienced user so much trouble.
Compiler options are set via the properties in the configuration files of the boards platforms. You can learn about the boards platform framework from the Arduino Platform Specification:
It is common convention for a platform to provide a set of "extra_flags" properties that are specifically dedicated for use by the user to inject additional flags into the compilation commands. For example, you can see them listed here in the platform.txt file of the "Arduino AVR Boards" platform:
As mentioned by the comment there, you can set your own values for these by adding a file named platform.local.txt:
Alternatively, you can set the values of platform properties via flags in the compilation command if you use the official Arduino CLI command line tool provided by Arduino:
--build-property stringArray Override a build property with a custom value. Can be used multiple times for multiple properties.
There is some discussion about this system here:
Just run the appropriate objdump command manually from the command line.
You can determine the path of the board's toolchain, and the compiled files by examining the verbose compilation output. If you are using Arduino IDE, you can obtain the verbose output by the following procedure:
Select File > Preferences... (or Arduino IDE > Settings... for macOS users) from the Arduino IDE menus.
The "Preferences" dialog will open.
Check the box next to "Show verbose output during: ☐ compile" in the "Preferences" dialog.
Click the "OK" button.
The "Preferences" dialog will close.
Select Sketch > Verify/Compile from the Arduino IDE menus.
Wait for the compilation to finish.
Now examine the contents of the black "Output" panel at the bottom of the Arduino IDE window.
Some 3rd party Arduino boards platforms do automatically generate a disassembly listing on each compilation. For example, here you can see it has been implemented in the excellent "MiniCore" platform:
and the referenced helper script that is used when compiling on a Linux or macOS machine:
Since you have not deigned to tell us which boards you are working with, we can't say whether one of those existing 3rd party platforms is relevant to your project, but you could always add the functionality to whichever platform you are using if you think it would be useful. You can implement it via a boards.local.txt file if you think it could be useful. You might even consider doing it via a global platform.txt file if you are working with multiple platforms, but it isn't guaranteed that the developers of every platform you are using have configured the platform in a consistent manner that would allow this (though most platform developers do follow the standard conventions for things like defining a property named compiler.objdump.cmd, so you might well be able to do so).
Arduino IDE 2.x has an integrated sketch debugger. There is information about it here:
Note that support for the debugger has been added to many platforms beyond the platforms of the boards specifically mentioned in those tutorials. However, this has not been done for all platforms. If you would tell us which boards you are working with, we could advise on the subject.
This is typically caused by having a different dependency environment on each machine. There might be differences in which libraries, or versions of libraries, you have installed on each machine. Likewise, there might be differences in which boards platforms, or versions of platforms, you have installed on each machine.
If you enable the verbose compilation output and then compile your sketch, you will see a list of the dependencies that were used in the compilation output. Compare the information from each machine to see if there is a difference between the two.
If you aren't sure how to interpret the output, just share it here and we'll assist.
In order to make things more approachable for new users.
It would actually be more accurate to say the main file wraps the .ino file. For example, here you see how the main.cpp file of the "Arduino AVR Boards" platform calls the setup and loop functions defined in the .ino file:
As I said, the design of Arduino is driven by the goal of making embedded systems accessible to everyone, while also providing a professional quality system that allows the creation of any advanced project.
have a look at ESP32 which has no problem with four independent PWM frequency and duty cycle outputs
plenty of GPIO etc etc
supported by the Arduino IDE
note it uses 3.3V logic
As mentioned different versions of the board package or different versions of libraries can cause this.
You can check this if you enable *Show verbose output during compilation under File → Preferences.
The first few lines tell you the version of the board package; e.g.
FQBN: arduino:avr:mega
Using board 'mega' from platform in folder: C:\Users\bugge\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6
Using core 'arduino' from platform in folder: C:\Users\bugge\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6
And after the message "Linking everything together" you can see the versions of the used libraries.
Linking everything together...
...
...
Using library List at version 3.0.1 in folder: C:\Users\bugge\OneDrive\Documents\Arduino\libraries\List
For me this often indicates memory issues related to writing outside the bounds of an array and hence overwriting other variables (including stack).
Lots of answers - none from OP. May be we should give him a chance to provide more context ?
My question would be about this
What type of control is expected ? Is the challenge in timing (fast bit banging or reliable sub microsecond timing?), setting specific PWM frequencies,… ?
I am trying to get it to work, I'm not trying to optimize. I'm asking if Arduino is doing something weird. I'm trying to figure out why this thing just refuses to work consistently
I inherited a project and I don't have the means or the time to switch now. It's plugged into custom hardware and operating in a wet lab. I don't have access to the ICSP pin header has the whole thing is covered up to protect it from the environment. It also needs to be programmable by the computer they have in the lab, which is not my development workstation and not even connected to the internet so any time I update I need to copy the project files over
thank you all, I actually didn't expect this much response. The project is a few files, and I'm uncertain if my contract would allow me to share the code. I know that's not helpful, it's been frustrating for me. I need the Arduino Bootloader so I can program it on site and use the usb-serial communication as that's the only access I have to the board (can't access the 6 pin header)
what board?
Arduino Duo Rev 3 plugged into a custom pcb that connects this to 6 sensors, 3 solenoid valves, and 6 motors (3 of which I'm trying to control with PWM signals, the other 3 don't matter at this point)
what Arduino version
been using the latest (2.3.6)
What Libraries
Outside of Arduino's headers and functions (Serial, millis(), digitalWrite(), analogWrite(), etc...) for the problem area I haven't been using libraries
Use VSCode
I have been using VSCode at my dev bench. At the target environment they only have Arduino IDE and that's all they need there just to program the board and talk to it over usb-serial
Pinout?
pin 5 -> solenoid valve 1 (D out)
pin 6 -> solenoid valve 2 (D out)
pin 7 -> solenoid valve 3 (D out)
pin 8 -> pump 1 (PWM out via analogWrite)
pin 9 -> pump 2 (PWM out via analogWrite)
pin 10 -> pump 3 (PWM out via analogWrite)
I'm not familiar with that board. Can you provide more information about it?
There is the Arduino Due, but that is not supported by either of the platforms you listed. There is also the Duemilanove, which is supported by the "Arduino AVR Boards" platform. However, that board model was retired many years ago and so is not often seen in use these days. So I'm doubtful whether you are using either of those.
Which specific one of those are you actually using? You can find out by looking at the board selection in Arduino IDE's Tools > Board menu. That menu is broken up into a separate submenu for each boards platform, so the boards platform in use is easily identified from the menu.
Alternatively, you can examine the verbose compilation output. The platform in use is shown there.