Simple addition of two numbers on Atmega328P simulation on Proteus - microcontroller

I'm new to simulation on Proteus using microcontroller. All the online beginners tutorial show how to flash LEDs using microcontrollers, I'm just curious cannot we just add two numbers and get the result as output without involving any LED?
Should I just write the adding integers code in C, convert to hex file and load it on ATMEGA328 ? Where (any particular port of the microcontroller) will I see the output? Do I need to specify that in that C code? Please guide me! And also any link doing this kindof stuff would be very helpful.Thanks!!

I think this question is wrong,Please provide enough details
Controller (AVR/PIC/ARM/TI)
8-bit/16-bit/32-bit
Compiler/IDE
In micro controllers you write any port(GPIO) and check your output.
If you don't want to see output with any output device led,7-segment,LCD display and etc then just write port directly and find your answer.
int main()
{
int x=10,y=20;
SET_PORT_DIRECTION = OUTPUT;
YOUR_CONTROLLER_PORT = x+y;
while(1);
}
In Proteus you will find which one YOUR_PORT led is on or off accordingly your output
if you used 8bit Microcontroller
You will able to write MAX Value 255 to the single port(in case of 8-bit micro controller)
X = 10, Y=20;
Then X+Y = 30;
HEX VALUE of 30 : 0x1E;
YOUR_PORT(8 bit) = 0 0 0 0 0 0 0 0;
YOUR_PORT = x+y;
YOUR_PORT = 0 0 0 1 1 1 1 0;
In Proteus
PORT_LED on/OFF :
LHB :
PIN : 0 STATE: OFF
PIN : 1 STATE: ON
PIN : 2 STATE: ON
PIN : 3 STATE: ON
PIN : 4 STATE: ON
PIN : 5 STATE: OFF
PIN : 6 STATE: OFF
PIN : 7 STATE: OFF
and also just used Digital Multi meter to check voltage on controller pins and check your answers.

Related

ESP32 Interrupt jitter at 20kHz

I would like your help to solve the following problem.
I'm using an ESP32 Dev Kit V1 connected as follows:
Pin 4 (input) is connected to a 20kHz and 3.3V signal and to channel 1 of the oscilloscope; and
Pin 2 (output) is connected to channel 2 of the oscilloscope.
My goal is to use interrupts and generate a signal on pin 2 (output) that follows the variations of the signal on pin 4 (input).
The image below illustrates two behaviors. The most frequent and the other one that happens occasionally.
In the first behavior, the latency is around 3 us, but sometimes there is a variation (jitter) and the rise of the output signal takes 15 us or even more to keep up with the input.
I would like to know how to remove this occasional behavior and keep the system stable.
The code that I'm using is below. To compile and upload I am using the latest Arduino IDE version 1.8.13.
I'm using GPIO.out_w1ts and GPIO.out_w1tc because I believe it will be faster than using digitalWrite(pin, state).
Also notice that I'm not reading the state of pin 4 (input) to be faster, because of this, sometimes the output signal gets inverted, but that's not a problem at this point.
#define OUTPUT_PIN 2
#define INPUT_PIN 4
volatile bool state = false;
void IRAM_ATTR interruptFunction() {
if (state)
GPIO.out_w1ts = 0b100;
else
GPIO.out_w1tc = 0b100;
state = !state;
}
void setup() {
pinMode(INPUT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INPUT_PIN), interruptFunction, CHANGE);
gpio_config_t io_conf;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = 0b100;
gpio_config(&io_conf);
}
void loop() {
}
The settings used in the Arduino IDE are illustrated in the next image.
Thanks in advance for all the help!

How to transfer an Integer from an Arduino to another Arduino?

So I have to write a code that recognizes colour using a colour-detector.
The because the colourpalette is limited to just 6 colours I can be saved as an Integer (Red as 0, Green as 1 aso.).
Now I have problems transfering the Integer from the Arduino that handles the detector to the Arduino I have to write code on.
I tried using the analog (A0) pin but with that I only ended up with a 19-20 whenever I tried to transfer anything at all.
Is there a solution to transfer an Integer from 0-5?
Thanks in advance
Using the Analog is not a good solution. You should use the "Serial Connection". It only requires two cables - no other electronics - and the code is very simple (see below).
If you just want to transfer values in the range 0-255 or smaller (as in your case: 0-5), you can use the "byte"-type variable. One or multiple bytes can easily be transferred using a serial connection, using the "TX" (transmit) and "RX" (receive) pins of the Arduinos. You just connect the TX pin from Arduino #1 to the "RX" pin of Arduino #2 - and: connect the GND pins of the two.
In the setup code for both, you need to start the serial connection with the same baud rate, e.g.
void setup(){
Serial.begin(9600);
}
Arduino #1 is sending a byte using the following command:
byte color = 0; // declare the variable "color"
color = 3; // set the variable to any value in the range [0-255]
Serial.write(color); // transmit the byte-variable "color"
Arduino #2 is receiving the byte. Therefore it needs to continuously check for new serial data.
void loop() {
byte data = 0;
// - check for new serial data - and respond accordingly
if (Serial.available() > 0) {
int x = Serial.read(); // The "Serial.read" command returns integer-type
data = x; //
// - now: do something with "data"
if (data == 0) {
// "red" was received ... do something ...
} else if (data == 1) {
// "green" was received ... do something ...
} else if (data == 2) {
// ... and so on, and so on ...
}
}
// ... do other tasks
}
Make sure that in the "other tasks" you are not using the command "delay", as this would prevent your code from checking the serial for new data in a timely manner.
In exactly the same way, your Arduino #2 could also send data back to Arduino #1. In that case, you add one more cable connecting "TX" from #2 to "RX" of #1, and use the same code as above, on the respective other Arduino.
Serial is most universal, as you can test/simulate/use it by a broad variety of partners.
Here, you might code your possible values as human readable characters { '0' .. '5' } or
{'R', 'G', 'B', 'C', 'M', 'Y'} or whatever you like.
Eventually, I2C is a better way of serial communication.
Of course, an analog signal can be divided into 6 clearly distinguishable areas, if it's more about states than about events. You need electronics (low pass filter) to turn analogWrite PWM into analog constant values. And eventually, you have to handle the state transitions separately.
(Huh, sounds pretty complicated, doesn't it :) )

Execute FlashForth word when pin changes

I have a word that I wish to trigger on pin change:
: example
." Hello, world! "
;i
I am using External Interrupt Request 1, which is interrupt vector no. 3 according to page 65 of the datasheet and this diagram I use.
' example 3 int!
ei
When I try to change the value of a pin (pin 3 in this case), nothing happens.
Am I doing something wrong?
There are several things wrong with the code I posted above, but I did get it working after looking at other examples and reading the data sheet:
\ Pin Change Interrupt 0
4 constant pcint0
\ Pin Change Mask Register 0
$6b constant pcmsk0
\ Pin Change Interrupt Control Register
$68 constant pcicr
ram variable example
: example+1
1 example +!
;i
: int-enable
['] example+1 pcint0 int!
ei
;
int-enable
%00000001 pcmsk0 mset
%00000111 $68 mset
\ Shorting pin 8 will now increment `example` variable.

Only receiving "<0><0><0><0><0><0><0>" on USART signal

When I try to receive the USART signal with my Silicon Labs CP210x USB to UART Bridge. The only thing I receive is:
<0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0> etc
I got the right settings selected: baud rate: 9600 data bits: 8 parity: none stop bits: 1
I use a ATmega128A3U. The test_LED (see code below) on port E pin 0 is working. I used a oscilloscope to check the uart signal. See picture here: http://imgur.com/dPxkdZ6
Does someone know a solution for this?
Does anyone know how to fix a framing error? (My UART software is giving this error)
CODE:
#define F_CPU (32000000UL) // CPU clock speed
#include <avr/io.h>
#include <util/delay.h>
void USARTF0_init() {
USARTF0_BAUDCTRLB = 0; //BSCALE is 0
USARTF0_BAUDCTRLA = 0xCF; //BSEL is 207
USARTF0_CTRLA = 0; //Disable interrupts
USARTF0_CTRLC = USART_CHSIZE_8BIT_gc; //8 data bits, no parity and 1 stop bit
USARTF0_CTRLB = USART_TXEN_bm | USART_RXEN_bm; // //Enable receive,transmit and high speed mode
PORTF_OUTSET = PIN3_bm; // Port F pin 3 as TX
PORTF_DIRSET = PIN3_bm; // TX pin as output
PORTF_OUTCLR = PIN2_bm; // Port F pin 2 as RX
PORTF_DIRCLR = PIN2_bm; // RX pin as input
}
void sendChar(char c) {
while( !(USARTF0_STATUS & USART_DREIF_bm) ); //Wait until DATA buffer is empty
USARTF0_DATA = c;
}
void sendString(char *text) {
while(*text) {
sendChar(*text++);
}
}
int main(void) {
USARTF0_init();
PORTE.DIRSET = PIN0_bm; // make port E pin 0 output (test_LED)
while(1)
{
_delay_ms(10);
sendString("Hello World!\n\r");
PORTE.OUTTGL = PIN0_bm; // test_LED Toggle
}
}
Code source: http://morf.lv/modules.php?name=tutorials&lasit=29
To recap the discussion, so it can useful to someone later.
If you have an oscilloscope, capture a trace for a simple test case, as #DrOctorooi has done with "#~00":
He has marked start and stop bits, and also the data bits (for serial/UART they're least-significant first)
This confirms that UART somehow works.
One should also confirm the voltage levels. 0-3.2V looks about right.
And the time base. On the captured trace it appears 1 bit takes 1.625ms, which means a baudrate of around 615. That's quite far from expected 9600. In fact, that's around 16 times slower.
Since the error has to do with time, the immediate questions are the MCU clock and UART clock dividers (and on more complex devices, and intermediate dividers and clocks).
It turns out the dividers were meant for the 32MHz clock, but this MCU has a clock of 2MHz when it comes out of reset (16 times slower, as we have seen above). Solution was to recalculate the dividers.

Issues reading button state in the serial monitor

i'm having some issues whit a little program in arduino with a button; i have a code that i make a little modified from the examples of the arduino's page.
the code is
const int buttonPin = 7; // the number of the pushbutton pin
int buttonState = 0;
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
buttonState = digitalRead(buttonPin);
Serial.println(buttonState);
}
Probably you will follow the simple idea, the program read the state of the button and send to the serial the value of the state.
The idea is, it will send something like
0
0
0
0
0
0
when the button is not pressed
and
1
1
1
1
1
1
when it is.
but i recieve something like this when it's not pressed
0
0
1
0
1
1
0
0
0
1
... i had this problems with other type of inputs but i just want tu figured it out this issue.
From what you explain, you connected the button to 5V. Then, when you press the button you are connecting the input to logical level 1. But when you release the button, Arduin's input is connected to nowhere. Which isn't 1 nor 0 logic level. That's why you get an ambiguous reading.
You have to put a pull-down resistor. That is a resistor between the input and GND. Usually 4k7 resistor is ok for that. Then when the button is released the input will sense a logic 0. This works the other way around too. You can place the button to connect to GND when pressed, and the 4k7 pull-up resistor to logic 1 (5 volt).
Furthermore, Arduino has bult-in pull up resistors for its digital input pins. Once you setup an input, you can turn the pull-up resistor with:
pinMode(pin, INPUT);
digitalWrite(pin, HIGH);
And then you don't need to use an actual resistor. That input will always read 1 unless you actually connect it to GND.

Resources