I have written below function and check it using Arduino MEGA. This code is simply read PORTC and filter it's 4bit and according to that bit values, function returns -2 to 13.
#define PDL_1_BRN 37 //PC0
#define PDL_2_GRN 36 //PC1
#define PDL_3_WHT 35 //PC2
#define PDL_4_YEL 34 //PC3
void setup() {
Serial.begin(9600);
pinMode(PDL_1_BRN, INPUT); //use external pullup
pinMode(PDL_2_GRN, INPUT);
pinMode(PDL_3_WHT, INPUT);
pinMode(PDL_4_YEL, INPUT);
}
uint32_t t = 0;
void loop() {
t = micros();
getPedalState();
Serial.println(micros() - t);
}
int8_t getPedalState() {
uint8_t val = 0;
val = PINC & 0x0F;
switch (val) {
case 0x0F:
return 0;
break;
case 0x0B:
return 1;
break;
case 0x09:
return 2;
break;
case 0x01:
return 3;
break;
case 0x05:
return 4;
break;
case 0x0D:
return 5;
break;
case 0x0C:
return 6;
break;
case 0x04:
return 7;
break;
case 0x00:
return 8;
break;
case 0x08:
return 9;
break;
case 0x0A:
return 10;
break;
case 0x02:
return 11;
break;
case 0x06:
return 12;
break;
case 0x0E:
return 13;
break;
case 0x07:
return -1;
break;
case 0x03:
return -2;
break;
}
}
Using separate code I measured PORTC read execution time using micros(). It takes 4uS as I measured.
This code also read the PORTC and then used a switch case to identify port value.
But, this entire function also gets only 4uS to execute all instructions (port reading, masking, switch case).
That means, switch case didn't take at least 1uS to execute.
As I know, swich case start to compare one by one top of the code to bottom of the code. (That means switch case gets more time to return value in bottom of the code.) But, this code gets only 4uS for any value of the PORTC.
Please explain how switch case works in Arduino/C++.
The resolution of the micros function is 4uS. That's why you're seeing the same values. Toggle a pin instead and watch it with an oscilloscope and you'll get a better idea of the actual timing.
Related
i have a question:
(i use winows, visual studio)
i making a program and i need to read keyboard and mouse input istantly so like getch() (because if i use cin i need to press fullstop new line evry time).
i have this:
char p;
while (running) {
if (_kbhit()) {
p = _getch();
switch (p) {
case 'w':
mx = -1;
map(player, mx, 0);
break;
case 'a':
my = -1;
map(player, 0, my);
break;
case 's':
mx = 1;
map(player, mx, 0);
break;
case 'd':
my = 1;
map(player, 0, my);
break;
case 27:
running = false;
break;
}
}
}
the problem is with _getch() i can't read mouse imput.
so how i can get this?
I want to set up a SPI connection between two mbed boards and I found that the spi.recieve() function which is used to detect the data transmission from the master always return zero and the connection can't be established.
I try to remove 'if' in my code, and it works, but I still don't understand why the function returns zero.
here is some code:
while (1)
{
transmit_value = 100 * voltage;
spislave.reply(transmit_value);
if (spislave.receive())
{
receive_value = spislave.read();
}
here is my completed code:
#include <mbed.h>
Serial pc(USBTX, USBRX);
SPISlave spislave(p5, p6, p7, p8);
AnalogIn voltage(p20);
PwmOut led(p21);
BusOut display(p9, p10, p11, p12, p13, p14, p15, p16);
DigitalOut GroundLeft(p27);
DigitalOut GroundRight(p28);
int main()
{
char transmit_value = 50;
char receive_value = 60;
spislave.format(8,0);
spislave.frequency(1000000);
while (1)
{
transmit_value = 100 * voltage;
spislave.reply(transmit_value);
if (!spislave.receive())
{
receive_value = spislave.read();
}
led.write(receive_value / 100.0);
int leftnum = receive_value / 10;
int rightnum = receive_value % 10;
pc.printf("%d\n", receive_value);
GroundLeft = 0;
GroundRight = 1;
switch (leftnum)
{
case 0:
display = 0x3F;
break;
case 1:
display = 0x06;
break;
case 2:
display = 0x5B;
break;
case 3:
display = 0x4F;
break;
case 4:
display = 0x66;
break;
case 5:
display = 0x6D;
break;
case 6:
display = 0x7D;
break;
case 7:
display = 0x07;
break;
case 8:
display = 0x7F;
break;
case 9:
display = 0x6F;
break;
}
wait(0.01);
GroundLeft = 1;
GroundRight = 0;
switch (rightnum)
{
case 0:
display = 0x3F;
break;
case 1:
display = 0x06;
break;
case 2:
display = 0x5B;
break;
case 3:
display = 0x4F;
break;
case 4:
display = 0x66;
break;
case 5:
display = 0x6D;
break;
case 6:
display = 0x7D;
break;
case 7:
display = 0x07;
break;
case 8:
display = 0x7F;
break;
case 9:
display = 0x6F;
break;
}
wait(0.01);
}
}
Why are you not following the reference code? https://os.mbed.com/docs/mbed-os/v5.9/reference/spislave.html
With SPI you have to understand that RX and TX happen at the same time and that the operation will take some amount of time.
.reply() sets up what to send, .receive() checks if something has been received (which probably won't be immediately), and .read() gets data from SPI controller.
I have a simple C++ program to store pressed keys in file.
What works is prinf to show it in console but fprintf to save it in file won't work.
Even fprintf(logx, "TEST"); works only when i delete while cycle.
My code:
int main(){
char c;
FILE *logx;
logx = fopen("mylog2.txt", "w");
fprintf(logx, "TEST");
while (true)
{
Sleep(10);
for (int i = 8; i <= 255; i++)
{
if (GetAsyncKeyState(i) == -32767)
{
switch(i) {
case 96:
fprintf(logx, "%d", 0);
break;
case 97:
fprintf(logx, "%d", 1);
break;
case 98:
fprintf(logx, "%d", 2);
break;
case 99:
fprintf(logx, "%d", 3);
break;
case 100:
fprintf(logx, "%d", 4);
break;
case 101:
printf("%d", 5);
break;
case 102:
printf("%d", 6);
break;
case 103:
printf("%d", 7);
break;
case 104:
printf("%d", 8);
break;
case 105:
printf("%d", 9);
break;
default:
c = char(i);
printf("%c", c);
break;
}
}
}
}
return 0;
}
File is empty after pressing all possible numbers. Not even TEST is written in file (when while cycle is deleted "TEST" is printed).
Thanks for any help or hint.
You must terminate the loop somehow. If you terminate your program with Ctrl-C the FILE I/O buffers will not be flushed and your file will be empty.
Alternatively you can put an fflush(logx); behind every individual fprintf() statement to force the data out to the file. But this is only a last resort as it makes file I/O very slow.
You should also close the file after the loop:
fclose(logx);
I first added an infinite loop. Dugme is a variable for loop. But I couldn't break the loop. That’s why, when I enter the loop, I can’t exit.
void otoac()
{
long duration, distance;
while(dugme==1)
{
int distanceR = 0;
int distanceL = 0;
delay(40);
if(distance<=24)
{
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
distanceR = lookRight();
delay(200);
distanceL = lookLeft();
delay(200);
if(distanceR>=distanceL)
{
turnRight();
moveStop();
}
else
{
turnLeft();
moveStop();
}
}
else
{
moveForward();
}
distance = readPing();
}
}
I have an code that when I click on case:'X' it goes in automatic mode (application). I have here the code for when I click out of 'X' that's 'x' (little x) it needs to stop but it doesn't stop. This is the code for the 'x'.
void otokapa()
{
dugme=0
motor1.setSpeed(0);
motor2.run(RELEASE); //turn motor1 off
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}
Someone on YouTube only gave me this answer:
I added a while loop to the command, as well as a contradiction to the command, meaning, the action that the car will do when the triangle is not pressed, which is nothing.
More code:
void loop(){
if(Serial.available() > 0){
command = Serial.read();
Stop();
switch(command){
case 'F':
forward();
break;
case 'B':
back();
break;
case 'L':
left();
break;
case 'R':
right();
break;
case 'G':
onsol();
break;
case 'I':
onsag();
break;
case 'H':
arkasag();
break;
case 'J':
arkasol();
break;
case 'W':
onac();
break;
case 'w':
onkapa();
break;
case 'X':
otoac();
break;
case 'x':
otokapa();
break;
}
}
}
and dugme:
on top of all the code int dugme=1; and dugme is only in void otokapa and in otoac while(dugme==1)
Is this in essence what your problem looks like?
int dugme = 1; // one and only definition of this (ODR)
void otoac() {
long duration, distance;
while(dugme==1) {
}
}
void otokapa() {
dugme=0;
}
void loop(){
if(Serial.available() > 0){
command = Serial.read();
Stop();
switch(command){
case 'X':
otoac();
break;
case 'x':
otokapa();
break;
}
}
}
Possible errors violation of ODR.
if loop and otoac runs in the same thread you will never get to the serial again.
About the Calculator:
Basically this calculator is made to calculate the resistance of copper and aluminum wires at the ambient temperature using the formula
R2= R1*(1+alpha(T-25))
Here R2 will be the output, R1 will be the value entered by the user using a 4x4 matrix keypad (which will include decimal values like 12.5 etc), T is the temperature in degree Celsius recorded by the temperature sensor LM35.
alpha for copper = 0.0039
alpha for aluminum = 0.0042
How it should work:
Basically the temperature will be recorded by the calculator which will give the input T. The value of resistance at 25deg C will be fed by the user using keypad.
Now the keys 0-9 and "." are used to enter the value.
After this when the user presses say "+" on keypad, it should implement the formula for copper and show the result on LCD, similarly when the user presses "-" it should implement the formula for aluminum. Let us leave the "*" "/" and "=" buttons as spare for the time being.
Progress till now:
Using the codes which I have sent you in this attachment, I am able to get the temperature on screen correctly, I am able to see the value of R1 (i.e value of resistance at 25deg C) Now I cannot figure out how to use these values to get the output.
Please help me with this. :)
Thanks & Regards,
Mohit Goyal
#define F_CPU 1000000UL
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include "lcd.h"
#include "lcd.c"
#include <math.h>
#define KB_PORT_OUT PORTB
#define KB_PORT_IN PINB
void port_init(void)
{
DDRB = 0x0f; //Key-board port, higer nibble - input, lower nibble - output
PORTB = 0xff;
}
void init_devices(void)
{
port_init();
MCUCR = 0x00;
TIMSK = 0x00; //timer interrupt sources
}
void InitADC()
{
ADMUX=(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
}
uint16_t ReadADC (uint8_t ch)
{
ch=ch&0b00000111;
ADMUX|=ch;
ADCSRA|=(1<<ADSC);
while (! (ADCSRA & (1<<ADIF)));
ADCSRA|=(1<<ADIF);
return (ADC);
}
void Wait ()
{
uint8_t i;
for (i=0;i<1;i++)
_delay_loop_2(0);
}
void main()
{
char Temp[3];
uint16_t adc_result,mV;
int t;
lcd_init (LCD_DISP_ON);
lcd_clrscr();
InitADC();
lcd_gotoxy(0,0);
lcd_puts("R1=");
lcd_gotoxy(9,0);
lcd_puts(",T=");
lcd_gotoxy(15,0);
lcd_puts("C");
lcd_gotoxy(0,1);
lcd_puts("R2=");
while(1)
{
adc_result=ReadADC(0);
mV=(int)(1000.0*5.0*(((float)adc_result)/1023.0));
t=(int)(mV/10);
sprintf(Temp,"%d",t);
lcd_gotoxy(12,0);
lcd_puts(Temp);
Wait();
unsigned char Res, upperNibble, myCharPointer, keyCode, keyPressed, j;
int a=0, b=0, c=0, d=0, display=0;
init_devices();
lcd_gotoxy(3,0);
while(1)
{
upperNibble = 0xff;
for(j=0; j<4; j++)
{
_delay_ms(1);
KB_PORT_OUT = ~(0x01 << j);
_delay_ms(1); //delay for port o/p settling
upperNibble = KB_PORT_IN | 0x0f;
if (upperNibble != 0xff)
{
_delay_ms(20); //key debouncing delay
upperNibble = KB_PORT_IN | 0x0f;
if(upperNibble == 0xff) goto OUT;
keyCode = (upperNibble & 0xf0) | (0x0f & ~(0x01 << j));
while (upperNibble != 0xff)
upperNibble = KB_PORT_IN | 0x0f;
_delay_ms(20); //key debouncing delay
switch (keyCode) //generating key characetr to display on LCD
{
case (0xee): keyPressed = "1";
a=1;
b=b*10+1;
break;
case (0xed): keyPressed = "4";
a=4;
b=b*10+4;
break;
case (0xeb): keyPressed = "7";
a=7;
b=b*10+7;
break;
case (0xe7): keyPressed = ".";
break;
case (0xde): keyPressed = "2";
a=2;
b=b*10+2;
break;
case (0xdd): keyPressed = "5";
a=5;
b=b*10+5;
break;
case (0xdb): keyPressed = "8";
a=8;
b=b*10+8;
break;
case (0xd7): keyPressed = "0";
a=0;
b=b*10+0;
break;
case (0xbe): keyPressed = "3";
a=3;
b=b*10+3;
break;
case (0xbd): keyPressed = "6";
a=6;
b=b*10+6;
break;
case (0xbb): keyPressed = "9";
a=9;
b=b*10+9;
break;
case (0xb7): keyPressed = "=";
break;
case (0x7e): keyPressed = "A";
break;
case (0x7d): keyPressed = "B";
break;
case (0x7b): keyPressed = "C";
break;
case (0x77): keyPressed = "D";
break;
default : keyPressed = "X";
}//end of switch
lcd_puts(keyPressed);
lcd_gotoxy(3,1);
lcd_puts(keyPressed);
OUT:;
}//end of if
}//end of for
}//end of while(1)
return 0;
}
}
One way to read input is read characters in character array(in your switch case block append keypressed to character array using strcat function). Then check whether it is in right format. And then convert the number in character array to float and use it in calculation as explained in question link
The way to append keypressed to string:
char s[25]="";
strcat(s,"1")
There is one error I noticed Change
keypressed="1"
to
keypressed='1'
in all such cases. "1" is const character array. '1' is character
or change the type of keypressed character array and use strcpy to assign any string to it.
strcpy(keypressed,"1")