girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

How set certain time for digitalwrite

Mon Nov 02, 2015 4:48 am

I'm new in programming with wiring pi :oops: :oops: and I want to set time for digital write with get time(NULL) after get key then stop writing (after certain time or with e key)and goto first of loop , my program doesn't work ,what is the problem?? :roll: :roll: I try with millis() but after 5sec val doesn't change auto to LOW until I press d or a val be LOW and goto first of the loop,Could this be another solution?

Code: Select all

void digital::loop(int motor_pin_1, int motor_pin_2, char key) {
time_t now,after;
	time_t second=10;
	printf("press 'd (<--open-->)' or 'a (-->close<--)' key OR 'e' to stop  and  change  mode:\n");

	do {
		key = getchar();
		now = time(NULL);
		after= now+ second;
		if (key == 'd') {
			 
			printf("<--open-->\n");
			digitalWrite(motor_pin_1, HIGH);
			digitalWrite(motor_pin_2, LOW);

		}

		else if (key == 'a') {
			printf("-->close<--\n");
			digitalWrite(motor_pin_2, HIGH);
			 digitalWrite(motor_pin_1, LOW);
			//delayMicroseconds(200);

			//	digitalWrite(motor_pin_1, LOW);
			//	digitalWrite(motor_pin_2, LOW);

		}

	} while (key != 'e' || now<after);
	
}

Code: Select all

void digital::loop(int motor_pin_1, int motor_pin_2, char key) {
	unsigned long  startTime;
	printf("press 'd (<--open-->)' or 'a (-->close<--)' key OR 'e' to stop  and  change  mode:\n");

do{
		key = getchar();
		 startTime = millis();
		if (key == 'd') {

			printf("<--open-->\n");
			digitalWrite(motor_pin_1, HIGH);
			digitalWrite(motor_pin_2, LOW);

		}

		else if (key == 'a') {
			printf("-->close<--\n");
			digitalWrite(motor_pin_2, HIGH);
			digitalWrite(motor_pin_1, LOW);
		}
			else if (key == 'e') {
break;

		}
	
}while (millis() - startTime <= 5000);

User avatar
joan
Posts: 15371
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How set certain time for digitalwrite

Mon Nov 02, 2015 11:45 am

The getchar function blocks until a carriage return is pressed.

girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

Re: How set certain time for digitalwrite

Mon Nov 02, 2015 5:10 pm

scanf, is the same does??

User avatar
joan
Posts: 15371
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How set certain time for digitalwrite

Mon Nov 02, 2015 5:20 pm

girl71 wrote:scanf, is the same does??
Yes, scanf does the same.

You will need to do raw IO. See the following example.

Call the file term.c

gcc term.c
./a.out

Press esc to finish.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>

struct termios orig_termios;

void reset_terminal_mode()
{
    tcsetattr(0, TCSANOW, &orig_termios);
}

void set_conio_terminal_mode()
{
    struct termios new_termios;

    /* take two copies - one for now, one for later */
    tcgetattr(0, &orig_termios);
    memcpy(&new_termios, &orig_termios, sizeof(new_termios));

    /* register cleanup handler, and set the new terminal mode */
    atexit(reset_terminal_mode);
    cfmakeraw(&new_termios);
    tcsetattr(0, TCSANOW, &new_termios);
}

int dataRdy(int fd)
{
    struct timeval tv = { 0L, 0L };
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(fd, &fds);
    return select(fd+1, &fds, NULL, NULL, &tv);
}

int getch()
{
    int r;
    unsigned char c;
    if ((r = read(0, &c, sizeof(c))) < 0)
    {
        return r;
    }
    else
    {
        return c;
    }
}

int main(int argc, char *argv[])
{
   int c;

   set_conio_terminal_mode();

   while(1)
   {
      if (dataRdy(0))
      {
         c = getch();
         printf("%c (%d)\n", c, c);
         if (c == 27) break; /* esc key */
      }
      usleep(1000);
   }

   reset_terminal_mode();
}

girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

Re: How set certain time for digitalwrite

Mon Nov 02, 2015 7:38 pm

your mean change 'd' to '100' of ascii value??If i change it the problem still exist :? :?

User avatar
joan
Posts: 15371
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How set certain time for digitalwrite

Mon Nov 02, 2015 9:13 pm

girl71 wrote:your mean change 'd' to '100' of ascii value??If i change it the problem still exist :? :?
No. I mean that you can not use getchar or scanf to do what you want. You must use non-blocking I/O as in the example I gave.

girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

Re: How set certain time for digitalwrite

Tue Nov 03, 2015 5:59 am

Thank you but,If I use part of your code, for stop program still need press key.......

Code: Select all

 int digital:: getch()
    {
        int r;
        unsigned char c;
        if ((r = read(0, &c, sizeof(c))) < 0)
        {
            return r;
        }
        else
        {
            return c;
        }
    }
void digital::loop(int motor_pin_1, int motor_pin_2, char key) {
	unsigned long  startTime;
	printf("press 'd (<--open-->)' or 'a (-->close<--)' key OR 'e' to stop  and  change  mode:\n");
	
do{
		key = getch();
		 startTime = millis();
	
		if (key == 'd') {

			printf("<--open-->\n");
			digitalWrite(motor_pin_1, HIGH);
			digitalWrite(motor_pin_2, LOW);

		}

		else if (key == 'a') {
			printf("-->close<--\n");
			digitalWrite(motor_pin_2, HIGH);
			digitalWrite(motor_pin_1, LOW);
			
		}
			else if (key == 'e') {
break;

		}
	
	} while (millis() - startTime <= 5000);
	
}

User avatar
joan
Posts: 15371
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How set certain time for digitalwrite

Tue Nov 03, 2015 8:35 am

You need all the code (apart from main) to put the system into non-blocking I/O. You can't pick and choose which parts might look relevant.

In your main you need to make the calls to set_conio_terminal_mode() at the start, reset_terminal_mode() at the end, and check dataRdy(0) before the getch().

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

Re: How set certain time for digitalwrite

Tue Nov 03, 2015 9:24 am

hey,
I just was running into this same issue,
now I found this code which is working fine, and even is quite quick:

Code: Select all

#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
 
int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;
 
  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
 
  ch = getchar();
 
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);
 
  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }
 
  return 0;
}
http://cboard.cprogramming.com/c-progra ... linux.html

HTH!
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

Re: How set certain time for digitalwrite

Tue Nov 03, 2015 10:01 am

oops it's better
Last edited by girl71 on Tue Nov 03, 2015 7:27 pm, edited 1 time in total.

girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

Re: How set certain time for digitalwrite

Tue Nov 03, 2015 7:16 pm

joan wrote:You need all the code (apart from main) to put the system into non-blocking I/O. You can't pick and choose which parts might look relevant.

In your main you need to make the calls to set_conio_terminal_mode() at the start, reset_terminal_mode() at the end, and check dataRdy(0) before the getch().

thank you very much for your help , it's work :lol: :lol: :lol: :lol:

girl71
Posts: 13
Joined: Mon Nov 02, 2015 4:31 am

Re: How set certain time for digitalwrite

Tue Nov 03, 2015 7:26 pm

@ davenull thank you

Return to “C/C++”