How do I rotate 2 steppers at the same time? - arduino

Is there somethimg like theading in arduino?
I'm using Stepper.h library to use steppers and I want to rotate two of them at the same time, is that possible?
Additional info:
I'm using two drivers ULN2003 and Arduino Nano to controll steppers.
Code for one of them:
void AStep(){
AStepper.step(i1.toInt());
display.println("Turned A stepper;");
display.display();
}

You can make them appeir as they are moving at the some time by making the stepper do smaller "steps".
The only thing is that this method DOESN'T make them turn in actual sync.
Snippet by PaulS from the Arduino forums.
for(int s=0; s<step_360; s++)
{
AStepper.step(1);
BStepper.step(1);
}

Related

Arduino ESP32 TwoWire "method" doesn't work

I have trouble using two sensors on two I2C interfaces.
The problem is, that I when I try to replace the Wire.begin() with something like this: I2C.begin(21, 22), my sensor QMC5883L returns for x, y and z 0. I included the Wire library manually and created a TwoWire object:
#include <Wire.h>
TwoWire I2C = TwoWire(0);
When I tried this, I commented the _wire->begin() in the library, It worked with the commented line and with Wire.begin() in the sketch, but when I try to replace Wire.begin() with I2C.begin(21, 22) it doesn't work anymore.
The reason, why this should work is that I want to create 2 interfaces like that and then give them to the compass.begin(&I2C) method. In the library I have this:
void QMC5883LCompass::init(TwoWire *theWire){
_wire = theWire;
_wire->begin(); // this is the line I commented, when getting the zeros...
_writeReg(0x0B,0x01);
setMode(0x01,0x0C,0x10,0X00);
}
Did I forget something?
Problem is that when calling _wire->begin() is actually calling the default definition (from Wire.h):
bool begin(int sda=-1, int scl=-1, uint32_t frequency=0);
Default parameters -1 for SDA/SCL means default pins, wich overwrites the ones you added in the first begin(...)
Presuming you are using https://github.com/mprograms/QMC5883LCompass, the solution is to subclass QMC5883LCompass and override the void QMC5883LCompass::init() or create a new init(...) with your specific needs.

Microcontoller AT89C52 - display with port 0

I write a program to display some number on 7seg dispaly by port 0. And i have a problem, if i want to do it with port for exmaple 2 i works great. By when i use port 0 it does not work. What i do wrong.
Here is my code:
#include <REGX52.H>
char wyswietlacz[2]={0x06, 0x06};
void wyswietlanie(){
P0=0x30 ;
P2_0=0x01;
P2_1=0x00;
P2_0=0;
P2_1=0;
P0=0x30 ;
P2_0=0;
P2_1=1;
P2_0=0;
P2_1=0;
}
void main(void){
while(1){
wyswietlanie();
}
}
And how it works:
Port 0 has open drain outputs, see its data sheet. That means that each pin can only sink current, but not source. How you did it, only "low" can be output, but not "high".
You can try to use pull-up resistors, which are needed if you use the port as general purpose I/O. However, I would not recommend this because the raising edge of a low-to-high change might be too slow. And it raises the power consumption.

ESP8266 "ovf" when doing small double maths

I'm using a Wemos D1 based on the ESP8266 wifi chip with the Arduino C framework to do some simple small math.
As far as I can gather, double precision is available so I'm using it - with a maximum of something like 1.8*10^103.
But I'm getting an ovf when I try to calculate a number around 5*10^8.
Any ideas please?
void setup(){
Serial.begin(9600);
while(!Serial);
Serial.println("Hit any key to start math");
double te = 6800;
double res = te * te;
Serial.println(res);
te = 68000;
res = te * te;
Serial.println(res);
te = 680000;
res = te * te;
Serial.println(res);
}
void loop(){
}
Prints
46240000.00
ovf
ovf
Arduino does supports 4-byte double data type. and your code is indeed produced a valid double value that is not overflow (ovf).
The problem that you see has to do with the way Arduino implement Serial.print() function which is almost like a half-cooked hack to support floating-point and is not as reliable as vprintf() that is available in avr-libc. You can see the source code here which print ovf for anything bigger than 4294967040.0 or smaller than -4294967040.0. I thought that ESP8266 Arduino Core has fixed this instead of inheriting the ugly implementation of Arduino Serial.print(), but apparently not.
Luckily the ESP8266 Arduino Core does have a Serial.printf() method that provide better floating point rendering. This code will shows that your number is indeed a valid number for double data type.
void setup(){
Serial.begin(9600);
while(!Serial);
double te = 68000;
double res = te * te;
Serial.println(res); //this will produce 'ovf'
Serial.printf("Result=%f\n", res); //this will produce correct 4624000000.000000
}
Please noted that Serial.printf() is ESP8266 specific implementation to support full floating point vprintf() in the standard library. It is not available for standard Arduino Boards.
For Arduino boards, there is a way to use sprintf() which inherits from vprintf() to print the correct floating point with some twist on linker options during code compilation process. I have a blog post Do you know Arduino - sprintf() and floating point talk about how to do that.

Run arduino sketch from an sd card

Is it possible to put a sketch (.HEX file) to an SD card and run it from there?
My objective is to utilize SD storage instead of flash memory for a program.
If yes, are there any libraries doing exactly this?
All i found was "flashing arduino from sd card", which is not what i need.
UPDATE:
the sketch's loop calling is implemented in the bootloader.
so i assume there is something like this in the bootloader:
while(true)
{
call_sketch_loop();
}
can it be changed to this? :
//signature changed from void loop() to int loop()
while(true)
{
int retval = call_sketch_loop(); //get loop call's return value
if( 0 == retval )
continue; // if 0, iterate the loop as usual
else
{
//copy 1.HEX from sd to flash and reboot
copy_hex_from_sd_to_flash( retval + ".HEX" );
reboot();
}
}
change loop singature to int loop()
put {int}.HEX files to an SD card - 1.HEX , 2.HEX , 3.HEX
the loop() call returns 0
continue with next iteration as usual
the loop() call returns 2
copy file 2.HEX from SD card into program flash memory
reboot device
with this approach, we can run flash-capacity-exceeding programs if we split them up to smaller subprograms.
The technical term you are looking for is "SD card bootloader".
Have you looked into this: "https://github.com/thseiler/embedded/tree/master/avr/2boots"?
As far as I understand, 2boot will first load the hex into the flash and then execute it from there. This is not exactly what you are looking for (you want to load it directly to RAM, right?).
The problem with what you are looking for is that arduino's RAM is really small. And there is liittle advantage in loading directly to RAM. Therfore such library might not exist at all.
I can sugget a poor-mans approach for doing this. First write a sketch that contains a function that have an infinite loop inside it and inside this loop, put the code of your desired "loop". In the setup of the sketch take the pointer to this function and write sufficient ammount of bytes into a binary file on the SD card.
Then upload another sketch wich has an empty buffer. This sketch will load the binary file into it and refernce to it's beginning as a pointer to a function. Viola, you can now execute your "loop".
This is ugly and unless you have very specific and isoteric need for loading directly into RAM, I suggest to try the 2boot library.

Arduino Due output TIOA and TIOB without interrupts

I am an electrical student and want to use arduino due to generate pulses for driving MOSFETs. I am making a inverter and want to generate pulses. I have arduino due with me. My main aims are :
1) one software interrupt for sampling the next time period (this will be changing..). After three cycles I will analogRead() new value of time period and same continues .
2) During one time period,set by RC count of Timer channel TC0, I want to load RA0 and RB0 with appropriate counts to get output pulses with different duty ratios(depending on RA0 and RB0 values).
I wrote a program which gives software interrupts with TC3 which is working fine. i.e. I am able to load new values into RA0 and RB0 automatically for every new sampled value( every 3 cycles new values comes else same values will be loaded).
Now I also used TC0 (i used Olavi Kamppari's library) for stopping, loading new values and starting the timer.
when i checked PIO_PB25B_TIOA0 and PIO_PB27B_TIOB0 in the serial monitor i am getting 33554432,134217728 .
I am really confused.I expected a 1 and 0 output. I just want two pulses from TC0 without interrupt.I set the ACPA value to 3 (Toggle) and I enabled the clock to the timer as well.Still I am not getting the output.
So if possible please provide me a sample program that can output pulses from PB25 and PB27 (TIOA0 and TIOB0). Any help will be greatly appreciated.
Thanks for reading my question.
Thank you.
The following sketch outputs a 3 MHz signal on TIOA6 (Pin 5 from memory)
I am about to post a question regarding the same code - I want to get to 8 (and a little bit) MHz but have hit a conceptual brick wall!
Note that this is under development - the IRQ handler is not used - and the PMC_Enable_Periph should be referring to ID_TC6 (I believe) - then the IRQ handler can be placed in the dust bin of history!
void TC6_Handler()
{
TC_GetStatus(TC2, 0);
}
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
TC_Configure(tc, channel,
TC_CMR_WAVE |
TC_CMR_WAVSEL_UP_RC |
TC_CMR_TCCLKS_TIMER_CLOCK1|
TC_CMR_ACPA_TOGGLE ); // RC compare TOGGLES TIOA)smiley-wink;
TC_SetRA(tc, channel, 1); //50% high, 50% low
TC_SetRC(tc, channel, 1);
PIO_Configure(PIOC,
PIO_PERIPH_B,
PIO_PC25B_TIOA6,
PIO_DEFAULT);
TC_Start(tc, channel);
}
void setup(){
startTimer(TC2, 0, TC6_IRQn);
}
void loop(){
}

Resources