Microcontoller AT89C52 - display with port 0 - microcontroller

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.

Related

How do I rotate 2 steppers at the same time?

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);
}

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(){
}

Arduino Serial Output Dropping Characters

I have a bizarre one here with the serial output when trying to write some code for my Arduino Uno.
I have this proto-code:
MyClass myclass;
void setup()
{
Serial.Begin(9600);
Serial.println("Starting...");
}
void loop()
{
int status = myclass.DoWork();
Serial.println("Status: " + status);
}
class MyClass
{
int DoWork()
{
Serial.println("Doing some work...");
return 1;
}
}
Now when this runs I get the following output:
Starting...
Doing some work...
atus: 1
So the strange part is the "Status: 1" missing the first few characters. Is this because I am using serial in an object improperly or something?
I have noticed when I reference another library that also uses serial like MyClass does that I get other strange output behavior... so I assume that I am doing something wrong.
EDIT: In the end this turned out to actually be a memory issue. A library I was including was quite large and it was consuming the available memory. I found this by adding a few more debugging statements and found the corruption shifted around based on the string lengths and positions. By using the F() function I moved the strings to flash memory (e.g. I now run Serial.println(F("Starting...")); and it has corrected the strange output.
You cannot add strings and integers in C++. It would have been better for you if this failed to compile:
Serial.println("Status: " + status);
Instead the compiler guessed at something. It guessed wrong. Use this:
Serial.print("Status :");
Serial.println(status);
or for complete control of outputting numbers and strings learn to use C string formatting, sprintf()
In the end this turned out to actually be a memory issue. A library I was including was quite large and it was consuming the available memory. I found this by adding a few more debugging statements and found the corruption shifted around based on the string lengths and positions. By using the F() function I moved the strings to flash memory (e.g. I now run Serial.println(F("Starting...")); and it has corrected the strange output.
One more possible explanation.
I was running minicom to monitor, and I usually like that it auto-reconnects after resetting my device.
Well I minimized a terminal running minicom last night, and today I started a new instance that somehow also got connected to the same serial port (if that is even possible).
I think the two instances of minicom were each reading ~50% of the serial characters roughly at random, leaving me with quite a mess of text.

Arduino's analogRead() returns junk when I print via serial

I'm making a clock with the Arduino, and I want to make a button to set the time.
So, just to test, I pluged a wire in the Analog Input pin 0 and wrote two lines of code to read the pin and print it via Serial, but all I get is junk.
valm = analogRead(0);
Serial.println(valm);
And what I get from the serial monitor is this:
?j?d?±µ?Ê??jDd?±µ???ºjRd?±µ???ºj?d?±µ?Ê??j?d?±µ?É?ªjRd?±µ???ÊjRd?±µ???Âj?d?±µ????j?d?±µ?É??j
Rd?±µ????j?d?±µ???ºj?d?±µ?É??jRd?±µ????j?d?±µ?Ê?ÊjDd?±µ???Âj?d?±µ????j?d?±µ?É??jRd?±µ????j?d
?±µ?É?ÂjRd?±µ???Êj?d?±µ???ªj?d?±µ?Ê?Êj$d?±µ???ÂjRd?±µ????j?d?±µ????jdd?±µ????jRd?±µ???Âj?d?±
µ?É?ÊjRd?±µ????j?d?±µ?Ò?Êj?d?±µ?É?ÂjRd?±µ????j?d?±µ????j?d?±µ?É??jRd?±µ???Âj?d?±µ???Êj?d?±µ?
??ªj?d?±µ???Êj?d?±µ???ÂjRd?±µ????j?d?±µ????j?d?±µ?É??jRd?±µ???Âj?d?±µ?Ò?Êj?d?±µ?É?ªj?d?±µ?É?
?jTd?±µ???Âj?d?±µ????j?d?±µ?É??jRd?±µ????j?d?±µ?É?ÂjRd?±µ???Êj?d?±µ?É?ªjRd?±µ???Êj?d?±µ???ºj
?d?±µ?È??jTd?±µ????jRd?±µ???ªj?d?±µ?È?ÂjTd?±µ?É?ÊjRd?±µ???ªj?d?±µ???Êj?d?±µ???ºj?d?±µ?É??jRd
?±µ???Êj?d?±µ???ªj?d?±µ?É?ÂjPd?±µ???Êj?d?±µ???ªj?d?±µ?Â?Êj?d?±µ?É?ºjRd?±µ????j?d?±µ?É??jRd?±
µ???ªj?d?±µ?Ê?Âj?d?±µ???ÊjRd?±µ???ªj?d?±µ?Ò?Êj?d?±µ???ºjRd?±µ????j?d?±µ???Êj?d?±µ?Ê?ªjdd?±µ?
??ÂjRd?±µ???Âj?d?±µ?É?ªjPd?±µ???Êj?d?±µ????j?d?±µ?É??jRd?±µ???Êj?d?±µ?É?ªjdd?±µ???ÂjRd?±µ???
Âj?d?±µ?É?ªjDd?±µ???Êj?d?±µ?Ê??j?d?±µ?É??jRd?±µ???ÊjRd?±µ???ªj?d?±µ?Ê?ÂjPd?±µ???Âj?d?±µ???ªj
?d?±µ?É?Êjdd?±µ?É??jRd?±µ????j?d?±µ?É?Êj$d?±µ???ªjRd?±µ???Âj?d?±µ?Â?ÂjTd?±µ???ªj?d?±µ???Êj?d
?±µ????jRd?±µ????j?d?±µ?É?ÊjTd?±µ???ªjRd?±µ???Âj?d?±µ???Âj?d?±µ?É?ªjRd?±µ???ÊjRd?±µ?Ò??jTd?±
µ????j?d?±µ???Êj
Why?
Edit:
I had set the digital pin 0 to output, and I thought maybe that was the problem so I went to the Arduino website and found the page Analog Input Pins.
So I tried to read from pin 14 which they say is the analog input pin 0, but I got the same output.
By the way, I'm trying to read from the analog only pins, not the one wich are also digital.
Try running this sample code found on the Arduino website. You shouldn't need to convert the variable valm or anything.
/*
Analog input
Reads an analog input on analog in 0, and prints the value out.
Created 24 March 2006
by Tom Igoe
*/
int analogValue = 0; // Variable to hold the analog value.
void setup() {
// open the serial port at 9600 bit/s:
Serial.begin(9600);
}
void loop() {
// Read the analog input on pin 0:
analogValue = analogRead(0);
// Print it out in many formats:
Serial.println(analogValue); // print as an ASCII-encoded decimal
Serial.println(analogValue, DEC); // print as an ASCII-encoded decimal
Serial.println(analogValue, HEX); // print as an ASCII-encoded hexadecimal
Serial.println(analogValue, OCT); // print as an ASCII-encoded octal
Serial.println(analogValue, BIN); // print as an ASCII-encoded binary
Serial.println(analogValue, BYTE); // print as a raw byte value
// Delay 10 milliseconds before the next reading:
delay(10);
}
If your output is still gibberish, there's something wrong with your serial terminal.
The problem Here is analog device you might connected are not # same ground potentials.
Example: If your powering on Arduino board using PC and sensor is powered on using other source , But You trying to read value from Arduino port, for this instant it gives above error. Try this power on arduino and sensor from Same power source and try to read data using Serial Port through DOcklight you will get Problem solved.
You need to set the baud rate in the serial monitor window (bottom right corner) to the same value that has been set in your code (e.g. Serial.begin(9600);).
From what your output looks like, it seems like you need to convert valm into a string, so that you can print the value numerically.
Also, is the wire you plugged into analog in floating? Because if it is, it'll just act like an antenna and grab random noise (though, might have a strong 60Hz component).

Resources