Why does Arduino require a void loop() even if it’s empty - arduino

Today i had my 10th, or 12th hour of Arduino in University, we were assigned a paper with only 2 parts, the questions and a picture of a TinkerCAD circuit, we had to wire this circuit, then wrote a code to light up the LED
TinkerCAD Circuit
i know void setup(){} runs only once, and that void loop(){} loops forever, i wrote the following code to light up the led
void setup(){
pinMode(7,OUTPUT);
digitalWrite(7,HIGH);
}
but Arduino expected a void loop()at the end, even if its empty, why is that?, why cant it run without it since an empty loop is essentially the same as no loop?, what is the reason the compiler cant ignore the lack of a void loop?

What you see in your Arduino sketch is not everything that will be executed in the Arduino board.
Instead they provide you with some friendly functions, so it's easier for makers to easily produce code for the Atmega microcontrollers present in the Arduinos.
You can imagine that there's the following pseudo-program executing in the background of what you see
setup();
while (true) {
loop();
}
So this program requires you to have a function called setup and a function called loop.
The setup will be called once at the beginning, and the loop will be called again and again in an infinite loop
Leaving loop empty if you don't need it to do anything is perfectly fine, but it's mandatory that you define such function.

Related

Trouble speeding up arduino

I'm trying to speed up my Arduino code by direct writing to registers. I wrote a short test script, but it doesn't seem to do much. If I use the 'digitalWrite()' function I can see an output on the oscilloscope, but using this code it just stays 0.
I used this link as a reference. I can't quite grasp what I missed.
byte *outputRegister;
byte bitMask;
void setup() {
pinMode(8,OUTPUT);
outputRegister = portOutputRegister(8);
bitMask = digitalPinToBitMask(8);
}
void loop() {
*outputRegister |= bitMask;
delay(1);
*outputRegister &= ~bitMask;
delay(1);
}
EDIT: The portOutRegister should return the port where the output pins are set. The digitalPinToBitmask function returns a bitmask (something like 0b00000001 for the first pin on the respective port).
With some further testing, I concluded that the digitalWrite function doesn't seem to actually change the values in these registers, which does nothing more than confuse me.
Arduino, if its Model = Uno, then it is ATmega-328 AVR, the best way to solve critical timing issues and achieve better execution times and code optimizations you should program via direct register modifications. That being said, use AVR-GCC, include and then do bit twiddling. Your code is not readable and hard to understand.
IMO you should either write in C++ inside Arduino IDE >> slower but easier option, or
start programming outside IDE inC and directly the AVR, >> orders of magnitude performance increase. Get to know the AVR Freaks Forum.

Run non blocking steppers with serial communication on arduino

I want to drive up to 10 stepper motors at the same. All with a constant but individual speed. Meanwhile other calculations and data transfer is to be done.
All Steppers have their own driver with dir/step pin. I use AccelStepper for non blocking functions to run the steppers. It is very important that the steppers run as smooth as possible.
First I simply put the runSpeed function for every stepper in the main loop, resulting in stuttering when data was written to the serial by the arduino. I now use Timer5 of the Mega to run a function that does nothing but call all runSpeed functions every 200 µs or so. This works very good with the steppers and the rest of the code except for the serial communication. I want to send commands to the arduino but with the interrupt being active some bytes never reach the arduino. Right now I am sending a notification byte that data will be transfered, the arduino answers and stops the interrupt, receives the command and starts the interrupt again. Works like a charm except for the 0.5 s stepper pause inbetween. This is to be solved.
Now I thought about the following:
1. Making the interrupt adoptable. Means: Track alls steps on every motor and calculate when a motor has to do the next step. Make the timer interrupt at exactly that time. Of course the interrupt has to be adjusted after every step of any motor. My fear is that the time demand for the calculations would be quite high, if not too high, so that the arduino gets stuck in interrupts and does not execute other code anymore.
2. Using a second arduino which only runs the steppers in the loop so the timing is no problem and serial data can be received. However, if I want that arduino to confirm the new settings to the main arduino, then I will get short pauses again... Solution would be to switch to interrupts when sending data, else use the main loop (sending data with interrupt works, receiving has the issue).
This is my idea of how to do it. But before I put all the effort in it, I wanted to discuss this with you and ask you, if you have another, better solution that for me.
I attached an exemplary code which with which the arduino cannot receive longer texts without missing bytes.
#include "AccelStepper.h"
#include "TimerFive.h"
AccelStepper m1(AccelStepper::DRIVER, 24, 25);
AccelStepper m2(AccelStepper::DRIVER, 26, 27);
AccelStepper m3(AccelStepper::DRIVER, 28, 29);
void setup() {
m1.setMaxSpeed(1000);
m2.setMaxSpeed(1000);
m3.setMaxSpeed(1000);
m1.setSpeed(50);
m2.setSpeed(70);
m3.setSpeed(90);
Timer5.initialize(250);
Timer5.attachInterrupt(run);
}
void run() {
m1.runSpeed();
m2.runSpeed();
m3.runSpeed();
}
void loop() {} {
//some calculations...
if (Serial.available() > 0) Serial.println(Serial.readString());
delay(1000);
}

Arduino serial print

I know this sounds really silly, but I really can't figure it out. I'm loading the following arduino code on an arduino uno:
void setup() {
Serial.begin(9600);
Serial.println("HELLO");
}
void loop() {
// put your main code here, to run repeatedly:
}
I'm uploading the code on the board and if I open a serial monitor repeatedly, I get different outputs. I'm expecting the output HELLO, and I get that sometimes. But I also get outputs like: HELLHELLO or HHELLO. I also loaded the same code on an arduino nano and it behaves similar.
Can someone please explain why this is happening? Is this an issue?
This could be due to the usb to serial buffer still containing data from the previous reset.
Try storing the string in PROGMEM to keep the string in flash memory rather than in RAM and see if that helps.
You need to set the baud rate to match to 9600 in the serial monitor, mismatched rates can cause unexpected output like you saw.

Erase and reset my arduino

By some reason, I wrote the code below and upload it into my arduino, and obviously, I forget a delay function in loop method.
So, every time I pin the arduino into my computer, the simulated keyboard is always input something and can not stop.
I want to erase or reset my arduino, but how can I work it?
Type of board is Leonardo Micro Mini.
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
Keyboard.print("Hello.");
}
I think the problem here is that it's difficult for you to upload, for instance, the BareMinimum example because of the Arduino printing "Hello." on your keyboard.
Is this right? If so, I see three possible solutions.
unplug the arduino, load the BareMinimum example, push the "Load" button and, when the compilation starts, plug the arduino back. It should start printing "Hello" but, in the end, it should load the sketch on the leonardo.
keep the reset button pressed; hit the load button in the IDE, then, as soon as the IDE says "loading" (after the compilation) release the switch. An alternative is to just press the reset button at the right moment, but I think that keeping it pressed is less annoying
use a programmer (or even another arduino - google for Arduino as ISP for more infos) to load the bootloader again on the leonardo
Bye

Arduino Uno - Light Switch

The function of the program I am writing is to stream incoming analog data from a sensor to a program on my computer across the USB port. For a little fun, I've decided to add a button to the program that will turn on/off a lamp. The lamp will be connected to a relay, which is connected to the arduino. I know how to go about programming it, but I want to know if this will interrupt the sensor data transfer?
I will get the current state of the light (HIGH(1) or LOW(0)) from the arduino when the button is pressed, then write to the arduino (HIGH(1) or LOW(0)) depending on the current state. I have a 5 second delay between each loop of the arduino program, for reasons related to the sensor output; however, I think I'm going to have to change this so that when the button is pressed, it is not missed by the arduino loop, or is that not possible?
I thought I read somewhere that you can't transmit/receive streaming data on the same serial line...in which case, I will need the Mega.
You have to remember and think of the Arduino as a single threaded device. While it is doing anything it is not able to do anything else. Period! In regard to the serial port however, the buffer will still accept incoming data on RX, however if an overflow situation occurs whilst blocked, management is impossible.
See the following taken directly from the Arduino reference
Certain things do go on while the delay() function is controlling the Atmega chip however, because the delay function does not disable interrupts. Serial communication that appears at the RX pin is recorded, PWM (analogWrite) values and pin states are maintained, and interrupts will work as they should. Reference
Now in saying that when you are setting the delay to 5 seconds between loops ( delay(5000) ) you are essentially blocking it from doing anything else almost full stop.
The Arduino framework exposes a a counter ( millis() ) that basically runs from the moment of boot for roughly 50 days in increments of one (1) millisecond. See Arduino - millis()
In your application you would define (remember) what loop you were due to run & when the said loop had finished so to not allow the other loop to run until the millis() counter was a defined amount more than your count. (Remember to define the count as a long)
Then what you do is move your loops out into separate functions that will only execute if the if statement return true...
for example...
long interval = 5000; // Define interval outside of the main loop
long previousCount = 0; // Used to store milli count when finished
int loopPosition = 1;
void loop()
{
if ((long)millis() - previousCount >= 5000 )
// This if statement will only return true every 5 seconds (5000ms)
{
if (loopPosition == 1)
{
function_One();
previousCount = millis(); // Redefine previousCount to now
loopPosition++; // Increment loop position
}
else if (loopPosition == 2)
{
function_Two();
previousCount = millis();
loopPosition--; // Decrement loop position
}
}
// Do Anything Here You Want
// - While ever the if statement above returns false
// the loop will move to this without hesitation so
// you can do things like monitor a pin low / high scenario.
}
void function_One()
{
// Do Your First Loop
}
void function_Two()
{
// Do Your Second Loop
}
The above will stop any delay you are using from blocking awesomeness, and to more of a point, almost make delay obsolete if implemented correctly under the right scenarios.
In regard to your serial data comment, like i said at the top of this article, the Arduino can only do one thing at a time. Transmitting and receiving at exactly the same time is impossible even with the Mega. In saying that a board like the 'Uno' for example is only capable of one serial interface, where as the 'Mega' is capable of four.
Best of luck....
NB- For a beginner reading this, the following tutorial / example covers what i have above in fairly simple terms and is a great building block for further awesomeness! Arduino - Blink Without Delay

Resources