can i read/write to /sys/class/gpio/gpio21/value using python with a delay. or its better to listen to serial port ttymxc3? for eg: while true: open file to read read file close file if value is 1: do something delay
If you're asking whether it's safe to write to GPIO outputs directly from the i.MX6 processor (Linux side) rather than the SAM3X (Arduino), that's perfectly fine so long as both chips aren't trying to write conflicting signals to the same pin, one pulling it high and the other low. All pins on the SAM3X side default to high-impedance inputs, so if you aren't using the Arduino section at all, or are running a sketch that doesn't do anything with the pins in question there should be no trouble. The only exception I've found has been a single pin, "CANTX" aka D69 -- that one defaults to an Arduino output, so if you want to use Linux gpio8 on the i.MX6, or the i.MX6 CAN bus you'd need to first do pinMode(69, INPUT); in setup() on the Arduino... or just pick a different pin and avoid that single one. Or hold the SAM3X in RESET, if it's not being used ( echo 0 >/gpio/gpio0/value ). Again, only an issue for D69. Using a given pin as an input to both CPUs simultaneously, or as an output on one and an input to the other is also OK, in case that's ever useful. Check these documentation files for help in matching up Linux gpio's with the corresponding Arduino pins: http://udoo.org/download/files/pinout/U ... iagram.pdf http://udoo.org/download/files/pinout/U ... _table.pdf
thank you, very helpful one more question which is better 1. open /sys/class/gpio/gpio21/value from python and write to file or 2 pass shell command in python for eg: echo 1 > /sys/class/gpio/gpio21/value or any other way? I am trying to build a internet radio using mpd, mpc and to have next,pre(maybe Rotary Encoders) ,Play/Pause and Two line 16 character LCD. There are many tutorial how to do this in Raspberry PI but i couldn't find any for udoo. Thank you
It's more efficient to open the /dev/gpio/* files and write to them directly from your code, especially since you can hold the file descriptors open for multiple write cycles, like sending a stream of characters to an HD44780-type LCD (with each nibble in that stream requiring 5-6 separate GPIOs to be toggled) . Spawning a shell command for each operation has significant overhead, and also would repeat the open() and close() calls (the shell doing that on your behalf) for every update to every signal. For GPIO input from buttons and such, you'd ideally want to have those pins generate interrrupts so they don't have to be constantly polled. I think this is possible, since the /dev/gpio/gpioXX/ pseudo-directories contain an "edge" file, but haven't tried it myself. It may be easier to have the SAM3X chip monitor your buttons, handle any debouncing, etc. and relay them across via ttymxc3.
Here is some C code I wrote for sending text to an HD44780 on the Udoo, which might be useful as a template for yours. Note the particular pins I used, which you'll probably want to change... I picked GPIO's all on a single row of the double-wide header (with GND and +5V at either end) while trying to avoid the ones also usable for SPI buses, UARTs etc. so that those remained free for future expansion. These displays seem happy to accept 3.3V signals (they do need +5V for power and contrast bias), just be sure R/W is pulled low, tied to ground, so that the LCD never tries to send any data back at 5V levels. Code: // jnh - based on Adafruit Adafruit_CharLCD_IPclock_example.py // 2014-07-07 #include <stdio.h> #include <stdlib.h> #include <error.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> // commands #define LCD_CLEARDISPLAY 0x01 #define LCD_RETURNHOME 0x02 #define LCD_ENTRYMODESET 0x04 #define LCD_DISPLAYCONTROL 0x08 #define LCD_CURSORSHIFT 0x10 #define LCD_FUNCTIONSET 0x20 #define LCD_SETCGRAMADDR 0x40 #define LCD_SETDDRAMADDR 0x80 // flags for display entry mode ( | LCD_ENTRYMODESET = 0x04 ); #define LCD_ENTRYRIGHT 0x00 #define LCD_ENTRYLEFT 0x02 #define LCD_ENTRYSHIFTINCREMENT 0x01 #define LCD_ENTRYSHIFTDECREMENT 0x00 // flags for display on/off control ( | DISPLAYCONTROL = 0x08 ) #define LCD_DISPLAYON 0x04 #define LCD_DISPLAYOFF 0x00 #define LCD_CURSORON 0x02 #define LCD_CURSOROFF 0x00 #define LCD_BLINKON 0x01 #define LCD_BLINKOFF 0x00 // flags for display/cursor shift ( | LCD_CURSORSHIFT = 0x10 ) #define LCD_DISPLAYMOVE 0x08 #define LCD_CURSORMOVE 0x00 #define LCD_MOVERIGHT 0x04 #define LCD_MOVELEFT 0x00 // flags for function set ( | LCD_FUNCTIONSET = 0x20 ) #define LCD_8BITMODE 0x10 #define LCD_4BITMODE 0x00 #define LCD_2LINE 0x08 #define LCD_1LINE 0x00 #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 int RS, EN, D[8]; unsigned char displaycontrol=0, displayfunction=0, displaymode=0; pulse_en () { write(EN, "1",1); usleep(2); write(EN, "0",1); usleep(1); write(EN, "1",1); usleep(2); } write1nibble(unsigned char nib) { write(RS, "0", 1); write(D[7], (nib & 0x8) ? "1" : "0", 1); write(D[6], (nib & 0x4) ? "1" : "0", 1); write(D[5], (nib & 0x2) ? "1" : "0", 1); write(D[4], (nib & 0x1) ? "1" : "0", 1); usleep(20); pulse_en(); usleep(40); } writenibbles(unsigned char value, char mode) { unsigned char nib; //fprintf(stderr,"sending %X / %d]\n",value, mode); write(RS, mode ? "1" : "0", 1); /* high nibble first */ nib = (value >> 4); write(D[7], (nib & 0x8) ? "1" : "0", 1); write(D[6], (nib & 0x4) ? "1" : "0", 1); write(D[5], (nib & 0x2) ? "1" : "0", 1); write(D[4], (nib & 0x1) ? "1" : "0", 1); usleep(20); pulse_en(); usleep(20); nib = (value & 0x0f); write(D[7], (nib & 0x8) ? "1" : "0", 1); write(D[6], (nib & 0x4) ? "1" : "0", 1); write(D[5], (nib & 0x2) ? "1" : "0", 1); write(D[4], (nib & 0x1) ? "1" : "0", 1); usleep(20); pulse_en(); usleep(100); } message (char *msg) { int j; for (j=0; (msg[j]!=0); j++) { if ((msg[j] == '\n' || msg[j] == '\r')) writenibbles(0xC0,0); /* next line */ else writenibbles(msg[j],1); } } main(int argc, char **argv) { int DIR; int i,s,gpio[] = { 33, 35, 205, 141, 139, 135 }; unsigned char tmp[256]; /* D7: 29 / gpio135 D6: 33 / gpio139 (ECSPI2_MISO, mirrored on 50) D5: 35 / gpio141 (ECSPI2_SCLK, mirroed on 52) D4: 39 / gpio205 EN: 41 / gpio35 RS: 43 / gpio33 */ for (i=0; i<6; i++) { sprintf(tmp, "/sys/class/gpio/gpio%d/direction",gpio[i]); if ( ( DIR=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { fprintf(stderr,"%s\n",tmp); perror("gpio_dir_setup"); exit(1); } write(DIR,"out\n",4); close(DIR); } sprintf(tmp, "/sys/class/gpio/gpio%d/value",gpio[0]); if ( ( RS=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio0_val"); exit(1); } write(RS, "0",1); sprintf(tmp, "/sys/class/gpio/gpio%d/value",gpio[1]); if ( ( EN=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio1_val"); exit(1); } write(EN, "1",1); sprintf(tmp, "/sys/class/gpio/gpio%d/value",gpio[2]); if ( ( D[4]=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio2_val"); exit(1); } write(D[4], "0",1); sprintf(tmp, "/sys/class/gpio/gpio%d/value",gpio[3]); if ( ( D[5]=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio3_val"); exit(1); } write(D[5], "0",1); sprintf(tmp, "/sys/class/gpio/gpio%d/value",gpio[4]); if ( ( D[6]=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio4_val"); exit(1); } write(D[6], "0",1); sprintf(tmp, "/sys/class/gpio/gpio%d/value",gpio[5]); if ( ( D[7]=open(tmp,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio5_val"); exit(1); } write(D[7], "0",1); /* init: enter & exit 8-bit mode to reset possible nibble misalignment... */ write1nibble(0x3); usleep(5000); write1nibble(0x3); usleep(5000); write1nibble(0x3); usleep(1000); write1nibble(0x2); usleep(1000); writenibbles(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS,0); usleep(50); writenibbles(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF,0); // 0x0C usleep(50); writenibbles(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT,0); // 0x06 usleep(50); writenibbles(LCD_CLEARDISPLAY,0); usleep(3200); if (argc > 2) { s=atoi(argv[1]); for (i=s;i<(s+16);i++) writenibbles(i,1); writenibbles(0xC0,0); for (i=(s+16);i<(s+32);i++) writenibbles(i,1); } else if (argc != 1 ) message (argv[1]); for (i=4; i<8; i++) { close(D[i]); } close(EN); close(RS); }
Thank you fetcher your C code really help me to change Adafruit_CharLCD.py for Raspberry pi to UDOO in python. Code: #!/usr/bin/python # for UDOO change by manikm - maldives # based on code from lrvick and LiquidCrystal # lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py # LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp # from time import sleep class Adafruit_CharLCD(object): # commands LCD_CLEARDISPLAY = 0x01 LCD_RETURNHOME = 0x02 LCD_ENTRYMODESET = 0x04 LCD_DISPLAYCONTROL = 0x08 LCD_CURSORSHIFT = 0x10 LCD_FUNCTIONSET = 0x20 LCD_SETCGRAMADDR = 0x40 LCD_SETDDRAMADDR = 0x80 # flags for display entry mode LCD_ENTRYRIGHT = 0x00 LCD_ENTRYLEFT = 0x02 LCD_ENTRYSHIFTINCREMENT = 0x01 LCD_ENTRYSHIFTDECREMENT = 0x00 # flags for display on/off control LCD_DISPLAYON = 0x04 LCD_DISPLAYOFF = 0x00 LCD_CURSORON = 0x02 LCD_CURSOROFF = 0x00 LCD_BLINKON = 0x01 LCD_BLINKOFF = 0x00 # flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 # flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 LCD_MOVERIGHT = 0x04 LCD_MOVELEFT = 0x00 # flags for function set LCD_8BITMODE = 0x10 LCD_4BITMODE = 0x00 LCD_2LINE = 0x08 LCD_1LINE = 0x00 LCD_5x10DOTS = 0x04 LCD_5x8DOTS = 0x00 # D7: 2 / gpio20 # D6: 3 / gpio16 # D5: 4 / gpio17 # D4: 5 / gpio18 # EN: 11 / gpio9 # RS: 12 / gpio3 def __init__(self, pin_rs=3, pin_e=9, pins_db=[18, 17, 16, 20], GPIO=None): # Emulate the old behavior of using RPi.GPIO if we haven't been given # an explicit GPIO interface to use # if not GPIO: # import RPi.GPIO as GPIO # GPIO.setwarnings(False) # self.GPIO = GPIO self.pin_rs = pin_rs self.pin_e = pin_e self.pins_db = pins_db # self.GPIO.setmode(GPIO.BCM) # self.GPIO.setup(self.pin_e, GPIO.OUT) self.setupdirection(self.pin_e, "out") # self.GPIO.setup(self.pin_rs, GPIO.OUT) self.setupdirection(self.pin_rs, "out") for pin in self.pins_db: #self.GPIO.setup(pin, GPIO.OUT) self.setupdirection(pin, "out") self.write4bits(0x33) # initialization self.write4bits(0x32) # initialization self.write4bits(0x28) # 2 line 5x7 matrix self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor self.write4bits(0x06) # shift cursor right self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS self.displayfunction |= self.LCD_2LINE # Initialize to default text direction (for romance languages) self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode self.clear() def setupdirection(self, pin, value): fs = open("/sys/class/gpio/gpio%d/direction" % pin, "w") fs.write("%s" % value) fs.close() def outputvalue(self, pin, value): fo = open("/sys/class/gpio/gpio%d/value" % pin, "w") if value: fo.write("1") else: fo.write("0") fo.close() def begin(self, cols, lines): if (lines > 1): self.numlines = lines self.displayfunction |= self.LCD_2LINE def home(self): self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero self.delayMicroseconds(3000) # this command takes a long time! def clear(self): self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time def setCursor(self, col, row): self.row_offsets = [0x00, 0x40, 0x14, 0x54] if row > self.numlines: row = self.numlines - 1 # we count rows starting w/0 self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row])) def noDisplay(self): """ Turn the display off (quickly) """ self.displaycontrol &= ~self.LCD_DISPLAYON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def display(self): """ Turn the display on (quickly) """ self.displaycontrol |= self.LCD_DISPLAYON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noCursor(self): """ Turns the underline cursor off """ self.displaycontrol &= ~self.LCD_CURSORON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def cursor(self): """ Turns the underline cursor on """ self.displaycontrol |= self.LCD_CURSORON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self): """ Turn the blinking cursor off """ self.displaycontrol &= ~self.LCD_BLINKON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def blink(self): """ Turn the blinking cursor on """ self.displaycontrol |= self.LCD_BLINKON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def DisplayLeft(self): """ These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT) def scrollDisplayRight(self): """ These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT) def leftToRight(self): """ This is for text that flows Left to Right """ self.displaymode |= self.LCD_ENTRYLEFT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def rightToLeft(self): """ This is for text that flows Right to Left """ self.displaymode &= ~self.LCD_ENTRYLEFT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def autoscroll(self): """ This will 'right justify' text from the cursor """ self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def noAutoscroll(self): """ This will 'left justify' text from the cursor """ self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def write4bits(self, bits, char_mode=False): """ Send command to LCD """ self.delayMicroseconds(1000) # 1000 microsecond sleep bits = bin(bits)[2:].zfill(8) #self.GPIO.output(self.pin_rs, char_mode) self.outputvalue(self.pin_rs, char_mode) for pin in self.pins_db: #self.GPIO.output(pin, False) self.outputvalue(pin, False) for i in range(4): if bits[i] == "1": #self.GPIO.output(self.pins_db[::-1][i], True) self.outputvalue(self.pins_db[::-1][i], True) self.pulseEnable() for pin in self.pins_db: #self.GPIO.output(pin, False) self.outputvalue(pin, False) for i in range(4, 8): if bits[i] == "1": #self.GPIO.output(self.pins_db[::-1][i-4], True) self.outputvalue(self.pins_db[::-1][i-4], True) self.pulseEnable() def delayMicroseconds(self, microseconds): seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds sleep(seconds) def pulseEnable(self): #self.GPIO.output(self.pin_e, False) self.outputvalue(self.pin_e, False) self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns #self.GPIO.output(self.pin_e, True) self.outputvalue(self.pin_e, True) self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns #self.GPIO.output(self.pin_e, False) self.outputvalue(self.pin_e, False) self.delayMicroseconds(1) # commands need > 37us to settle def message(self, text): """ Send string to LCD. Newline wraps to second line""" for char in text: if char == '\n': self.write4bits(0xC0) # next line else: self.write4bits(ord(char), True) if __name__ == '__main__': lcd = Adafruit_CharLCD() lcd.clear() lcd.message(" Adafruit 16x2\n Standard LCD")
Internet Radio Rotary Encoders I am trying to build internet radio from Udoo board currently can sent text from linux to 1602 lcd now i want to connect Rotary Encoder to use as a channel changer or tuner what is the most effective way to go ahead? any project/code i can study