Arduino mills() overflow - arduino-uno

I have motor programmed with arduino, the hardware is already setup so i don't want to change the micro controller. I need to give the motor 1 second to move from each point to the other and if its too much stay until "one second" is done and then go the rest of the code.
the bellow code this is part of the whole code. it freezes and not working after about 40 hour. please advise how can i prevent that. I know that the mills() function is the problem but don't know whats the best option to replace or prevent that?
unsigned long firsttime = 0;
unsigned long secondtime = 0;
void loop(){
...
firsttime= millis();
myStepper.step(RNum);
secondtime = 1000-millis()+firsttime;
delay (secondtime);
...
}
Thanks

Related

esp32: isolate gpio activities from runtime

i'm new with esp32 wroom. I'm trying to develop a system to drive a ws2812 led strip. The system needs to be controlled by a ble android app. For this reason i created a project from bluedroid gatt server demo in eclipse.
The ws2812 strips needs 3 bytes (RGB) for every led and every bit is discriminated bye the dutycycle of a square wave signal with period of about 1,25us.
i did a test writing code that write an out pin port with 1 and 0 with inside a while(true) loop. In this manner i reach the min period of about 1us. For this reason i choose to create a simple serial flow with a brutal way like this:
void ledStrip_send_bit0()
{
gpio_set_level(LED_STRIP_SIGNAL_OUT_GPIO, 1);
for(int i = 0; i < 0; i++);
gpio_set_level(LED_STRIP_SIGNAL_OUT_GPIO, 0);
for(int i = 0; i < 4; i++);
}
void ledStrip_send_bit1()
{
gpio_set_level(LED_STRIP_SIGNAL_OUT_GPIO, 1);
for(int i = 0; i < 4; i++);
gpio_set_level(LED_STRIP_SIGNAL_OUT_GPIO, 0);
for(int i = 0; i < 0; i++);
}
probably this is a bad way but this method works fine.
The problem detected is relate to the interrupts of the system sure enough any interrupt creates a margin of error in the timing of the control signal of led strip.
for this reason many leds works in a random way.
To write 128 leds the esp32 takes about 4ms so using taskDISABLE_INTERRUPTS(); befor port writing and taskENABLE_INTERRUPTS(); after it, the led strips is not affected by any random lighting.
In this way i'm also able to send a ble message to control the lights but i think that this is a bad way and i want to improve the entire system.
I tryed to use a task with other core to isolate the activities hoping uselessly to solve the problem.
So my question is:
can i solve increasing the cpu speed clock? how to do it?
There is a way to create a signal not affected by any cpu activities like interrups??
Thanks
Marco

XTestFakeKeyEvent calls get swallowed

I'm trying to spoof keystrokes; to be a bit more precise: I'm replaying a number of keystrokes which should all get sent at a certain time - sometimes several at the same time (or at least as close together as reasonably possible).
Implementing this using XTestFakeKeyEvent, I've come across a problem. While what I've written so far mostly works as it is intended and sends the events at the correct time, sometimes a number of them will fail. XTestFakeKeyEvent never returns zero (which would indicate failure), but these events never seem to reach the application I'm trying to send them to. I suspect that this might be due to the frequency of calls being too high (sometimes 100+/second) as it looks like it's more prone to fail when there's a large number of keystrokes/second.
A little program to illustrate what I'm doing, incomplete and without error checks for the sake of conciseness:
// #includes ...
struct action {
int time; // Time where this should be executed.
int down; // Keydown or keyup?
int code; // The VK to simulate the event for.
};
Display *display;
int nactions; // actions array length.
struct action *actions; // Array of actions we'll want to "execute".
int main(void)
{
display = XOpenDisplay(NULL);
nactions = get_actions(&actions);
int cur_time;
int cur_i = 0;
struct action *cur_action;
// While there's still actions to execute.
while (cur_i < nactions) {
cur_time = get_time();
cur_action = actions + cur_i;
// For each action that is (over)due.
while ((cur_action = actions + cur_i)->time <= cur_time) {
cur_i++;
XTestFakeKeyEvent(display, cur_action->code,
cur_action->down, CurrentTime);
XFlush(display);
}
// Sleep for 1ms.
nanosleep((struct timespec[]){{0, 1000000L}}, NULL);
}
}
I realize that the code above is very specific to my case, but I suspect that this is a broader problem - which is also why I'm asking this here.
Is there a limit to how often you can/should flush XEvents? Could the application I'm sending this to be the issue, maybe failing to read them quickly enough?
It's been a little while but after some tinkering, it turned out that my delay between key down and key up was simply too low. After setting it to 15ms the application registered the actions as keystrokes properly and (still) with very high accuracy.
I feel a little silly in retrospect, but I do feel like this might be something others could stumble over as well.

Arduino PWM program to generate a frequency in a loop

I am new to Arduino, and right now I am trying to generate a frequency that gradually decreases (without using the tone library) in a program that gradually increases the delay between the switching of the high and low. I have the arduino connected to an audio amp and a speaker.
For some reason, the speaker only outputs a single tone and I dont know why. Here is the code:
void setup()
{
pinMode(3, OUTPUT);
}
void loop()
{
for (int i=100; i <= 25500; i+100){
digitalWrite(3, HIGH);
delayMicroseconds(i);
digitalWrite(3, LOW);
delayMicroseconds(i);
}
}
Any help would be appreciated. I would prefer to try and do this the way I am doing, as opposed to using a completly different method or the tone library.
There is an error in the for statement: the increment statement is actually not a statement. You need to assign i to the new value, i.e. write i = i + 100 instead of just i + 100.

Arduino push Button

I need a help in arduino uno r3 with push button. By using the registers without using the pinMode, digitalWrite, digitalRead if-else, and switch-case.
int led1=2, led2=3, led3=4, led4=5;
int led5=8, led6=9, led7=10, led8=11;
int button=12;
int i,j,k;
void setup() {
DDRB=DDRB|B00001111;
DDRD=DDRD|B00111100;
Serial.begin (9600);
}
void loop() {
int f=0;
for(int s=0;s<16;s++){
int k=0;
int i=0b00001;
int j=0b0011;
PORTB=f;
f +=1;
if (f==64){f=0;}
PORTD=0;
for(k=0;k<7;k++){
delay(250);
PORTD=i;
delay(250);
PORTD=j;
i=(i<<1);
j=(j<<1);
}
j=(j>>1);
for(int d=0; d<9; d++){
delay(250);
PORTD=i;
delay(250);
PORTD=j;
i=(i>>1);
j=(j>>1);
}
}
}
This is the code. That what I need is to make a while loop for the push button. When I will push the button the program will be start and when I push the button again program will stop.
Well, you can do this in 2 way.
First one
The simple one is writing and reading a byte directly into/fom eeprom. Everytime you press the push button, you need to read it first and validate this value. Lets supose your byte means 0 to turned off and 1 to turned on. So if you push the button and the already saved byte is 0, so you need to change this to 1.
You are going to write using this:
https://www.arduino.cc/en/Tutorial/EEPROMWrite
After this management, you will need to read this byte constantly inside your loop statement. If byte is 1, so your thread can be executed.
You are going to read using this: https://www.arduino.cc/en/Tutorial/EEPROMRead
Second
This is a cannon to kill a mosquito, but can be reused later to manage other kinds of informations. You are going to use the same logic, but saving more detailed or complex values. We are talking about some kind of database.
http://playground.arduino.cc/Code/DatabaseLibrary
I'm sorry but I can't write to you a sample code right now. Job first. If you can't do this untill the end of the day, maybe I can come later and comlete this post to help you out.

alternating arduino outputs based on if statement

This is my first post on stackoverflow and one of my first arduino projects. Thanks for your help.
I am building a relay controller that alternates which battery is being charged based on an LED indicator light. I'm getting close, but I am having difficulty with the control logic.
I am able to read the LED and determine when the battery should be switched (my boolean variable says switch or don't). It also seems that a for statement is the best way to proceed to the next output. I found this example but it doesn't quite fit: http://arduino.cc/en/Tutorial/ForLoop
Looking for these states:
https://www.dropbox.com/s/ue192ebrhng3xcw/relaystates.jpg?dl=0
This is my first attempt:
for (int thisPin = 9; relayswitch = true; thisPin++){
// turn the last pin off:
digitalWrite(thisPin-1, LOW);
delay(2);
// turn the next pin on:
digitalWrite(thisPin, HIGH);
}
//resets relay switch indicator
boolean relayswitch = false;
What is your question?
One answer might be: you have implemented an endless loop.
for (...; relayswitch = true; ...){
// code that will not alter relayswitch
}
Notice that you do NOT check for a condition with the assignment operator "=". A condition would be checked with "==". Thus the "while condition" of the for loop will be true no matter what you do in the body of the loop. However even if you would check with "==" it would not matter as you do not alter this variable inside the loop.

Resources