Skip to main content

Easy Acces to digital GPIOs on arm platform

  • Karsten Hoffmann
  • Visitor
  • Visitor
8 years 10 months ago - 8 years 10 months ago #167 by Karsten Hoffmann
Easy Acces to digital GPIOs on arm platform was created by Karsten Hoffmann
It is possible to acces the GPIOs of an arm SOC like the BeagleBone Black in logi.CAD 3 compact.

Normaly In Linux on arm SOCs the GPIOs are mapped to the file system.
To get acces to Linux GPIO 66 on BeagleBone Black as digital input, you have to do something like this:
Code:
root@beaglebone:~# echo 66 > /sys/class/gpio/export root@beaglebone:~# echo in > /sys/class/gpio/gpio66/direction root@beaglebone:~# cat /sys/class/gpio/gpio66/value 1 root@beaglebone:~#

How to do this in logi.CAD 3 compact?

It is a little more complicated, so here is a function set to easy access the GPIOs
In these GPIO functions the ascii functions Asc and Chr are used.
Cause these functions are not implemented in logi.CAD 3 compact yet, you will need these functions too.
Listing is down below.

You also can download the two zip files and import them to your project.
Code:
/* * Function set to easy access digital GPIO's on arm platforms */ /* * initializes a GPIO <br> * <br> * takes the Linux GPIO Number as STRING<br> * <br> * example: <br> * initGPIO('66'); */ FUNCTION initGPIO VAR_INPUT gpio :STRING[3]; END_VAR VAR FD :DINT; data :ARRAY[0..63]OF BYTE; write :DINT:=1; length :UINT; count :UINT; openENO :BOOL; writeENO :BOOL; END_VAR length:=LEN(gpio); FD:=System_open(pathname:='/sys/class/gpio/export',flags:=write,ENO=>openENO); IF openENO THEN FOR count:=0 TO length-1 DO data[count]:=TO_BYTE(Asc(gpio[count+1])); END_FOR; System_write(fd:=FD,data:=data,count:=length,ENO=>writeENO); IF writeENO THEN System_close(fd:=FD); ENO:=TRUE; ELSE ENO:=FALSE; END_IF; ELSE ENO:=FALSE; END_IF; END_FUNCTION /* * deinitializes a GPIO <br> * <br> * takes the Linux GPIO Number as STRING<br> * <br> * example: <br> * deinitGPIO('66'); */ FUNCTION deinitGPIO VAR_INPUT gpio :STRING[3]; END_VAR VAR FD :DINT; data :ARRAY[0..63]OF BYTE; write :DINT:=1; length :UINT; count :UINT; END_VAR length:=LEN(gpio); FD:=System_open(pathname:='/sys/class/gpio/unexport',flags:=write); FOR count:=0 TO length-1 DO data[count]:=TO_BYTE(Asc(gpio[count+1])); END_FOR; System_write(fd:=FD,data:=data,count:=length); System_close(fd:=FD); END_FUNCTION /* * set a GPIO as input <br> * <br> * takes the Linux GPIO Number as STRING<br> * <br> * example: <br> * setGPIOinput('66'); */ FUNCTION setGPIOinput VAR_INPUT gpio :STRING[3]; END_VAR VAR FD :DINT; write :DINT:=1; pathName :STRING[255]; data :ARRAY[0..63]OF BYTE; openENO :BOOL; writeENO :BOOL; END_VAR // put 'in' to payload data[0]:=TO_BYTE(Asc('i')); data[1]:=TO_BYTE(Asc('n')); pathName:='/sys/class/gpio/gpio'; pathName:=CONCAT(pathName,gpio,'/direction'); system_open(pathname:=pathName,flags:=write,ENO=>openENO); IF openENO THEN system_write(fd:=FD,data:=data,count:=2,ENO=>writeENO); IF writeENO THEN ENO:=TRUE; ELSE ENO:=FALSE; END_IF; system_close(fd:=FD); ELSE ENO:=FALSE; END_IF; END_FUNCTION /* * set a GPIO as output <br> * <br> * takes the Linux GPIO Number as STRING<br> * <br> * example: <br> * setGPIOoutput('66'); */ FUNCTION setGPIOoutput VAR_INPUT gpio :STRING[3]; END_VAR VAR FD :DINT; write :DINT:=1; pathName :STRING[255]; data :ARRAY[0..63]OF BYTE; openENO :BOOL; writeENO :BOOL; END_VAR // put 'out' to payload data[0]:=TO_BYTE(Asc('o')); data[1]:=TO_BYTE(Asc('u')); data[2]:=TO_BYTE(Asc('t')); pathName:='/sys/class/gpio/gpio'; pathName:=CONCAT(pathName,gpio,'/direction'); system_open(pathname:=pathName,flags:=write,ENO=>openENO); IF openENO THEN system_write(fd:=FD,data:=data,count:=3,ENO=>writeENO); IF writeENO THEN ENO:=TRUE; ELSE ENO:=FALSE; END_IF; system_close(fd:=FD); ELSE ENO:=FALSE; END_IF; END_FUNCTION /* * open a GPIO to read or write <br> * <br> * takes the Linux GPIO Number as STRING<br> * and a flag: <br> * 0 for reading <br> * 1 for writing <br> * <br> * example: <br> * openGPIO('66',0); */ FUNCTION openGPIO :DINT VAR_INPUT gpio :STRING[3]; flag :DINT; END_VAR VAR FD :DINT; pathName :STRING[255]; openENO :BOOL; END_VAR pathName:='/sys/class/gpio/gpio'; pathName:=CONCAT(pathname,gpio,'/value'); FD:=System_open(pathname:=pathName,flags:=flag,ENO=>openENO); IF openENO THEN openGPIO:=FD; ENO:=TRUE; ELSE openGPIO:=-1; ENO:=FALSE; END_IF; END_FUNCTION /* * reads the value from a GPIO <br> * <br> * takes the Linux fileDescriptor <br> * given by the openGPIO function <br> * <br> * example: <br> * DI:=readGPIO(fileDescriptor); */ FUNCTION readGPIO :BOOL VAR_INPUT fileDescriptor :DINT; END_VAR VAR data :ARRAY[0..63]OF BYTE; readENO :BOOL; END_VAR System_read(fd:=fileDescriptor,data=>data,count:=1,ENO=>readENO); IF readENO THEN IF Chr(TO_USINT(data[0]))='1' THEN readGPIO:=TRUE; ELSE readGPIO:=FALSE; END_IF; ENO:=TRUE; ELSE readGPIO:=FALSE; ENO:=FALSE; END_IF; END_FUNCTION /* * writes value to a GPIO <br> * <br> * takes the Linux fileDescriptor <br> * given by the openGPIO function <br> * and the value as BOOL <br> * <br> * example: <br> * writeGPIO(fileDescriptor,TRUE); */ FUNCTION writeGPIO :BOOL VAR_INPUT fileDescriptor :DINT; value :BOOL; END_VAR VAR data :ARRAY[0..63]OF BYTE; writeENO :BOOL; END_VAR IF value THEN data[0]:=TO_BYTE(Asc('1')); ELSE data[0]:=TO_BYTE(Asc('0')); END_IF; System_write(fd:=fileDescriptor,data:=data,count:=1,ENO=>writeENO); IF writeENO THEN ENO:=TRUE; ELSE ENO:=FALSE; END_IF; END_FUNCTION

Here are the ascii functions used above:

You have to copy the VAR_GLOBAL CONSTANT section to your resource
Code:
// copy this to your resource // // VAR_GLOBAL CONSTANT // ascii_characters :ARRAY[0..255]OF CHAR := // [ // '$00','$01','$02','$03','$04','$05','$06','$07','$08','$09','$0A','$0B','$0C','$0D','$0E','$0F', // '$10','$11','$12','$13','$14','$15','$16','$17','$18','$19','$1A','$1B','$1C','$1D','$1E','$1F', // '$20','$21','$22','$23','$24','$25','$26','$27','$28','$29','$2A','$2B','$2C','$2D','$2E','$2F', // '$30','$31','$32','$33','$34','$35','$36','$37','$38','$39','$3A','$3B','$3C','$3D','$3E','$3F', // '$40','$41','$42','$43','$44','$45','$46','$47','$48','$49','$4A','$4B','$4C','$4D','$4E','$4F', // '$50','$51','$52','$53','$54','$55','$56','$57','$58','$59','$5A','$5B','$5C','$5D','$5E','$5F', // '$60','$61','$62','$63','$64','$65','$66','$67','$68','$69','$6A','$6B','$6C','$6D','$6E','$6F', // '$70','$71','$72','$73','$74','$75','$76','$77','$78','$79','$7A','$7B','$7C','$7D','$7E','$7F', // '$80','$81','$82','$83','$84','$85','$86','$87','$88','$89','$8A','$8B','$8C','$8D','$8E','$8F', // '$90','$91','$92','$93','$94','$95','$96','$97','$98','$99','$9A','$9B','$9C','$9D','$9E','$9F', // '$A0','$A1','$A2','$A3','$A4','$A5','$A6','$A7','$A8','$A9','$AA','$AB','$AC','$AD','$AE','$AF', // '$B0','$B1','$B2','$B3','$B4','$B5','$B6','$B7','$B8','$B9','$BA','$BB','$BC','$BD','$BE','$BF', // '$C0','$C1','$C2','$C3','$C4','$C5','$C6','$C7','$C8','$C9','$CA','$CB','$CC','$CD','$CE','$CF', // '$D0','$D1','$D2','$D3','$D4','$D5','$D6','$D7','$D8','$D9','$DA','$DB','$DC','$DD','$DE','$DF', // '$E0','$E1','$E2','$E3','$E4','$E5','$E6','$E7','$E8','$E9','$EA','$EB','$EC','$ED','$EE','$EF', // '$F0','$F1','$F2','$F3','$F4','$F5','$F6','$F7','$F8','$F9','$FA','$FB','$FC','$FD','$FE','$FF' // ]; // END_VAR /* * This function gives the ASCII code of a character */ FUNCTION Asc :USINT VAR_EXTERNAL CONSTANT ascii_characters :ARRAY[0..255]OF CHAR; END_VAR VAR_INPUT character :CHAR; END_VAR VAR count :USINT; END_VAR FOR count:=0 TO 255 DO IF character = ascii_characters[count] THEN Asc:=count; END_IF; END_FOR; END_FUNCTION /* * This function gives a character from an ASCII code */ FUNCTION Chr :CHAR VAR_EXTERNAL CONSTANT ascii_characters :ARRAY[0..255]OF CHAR; END_VAR VAR_INPUT num :USINT; END_VAR Chr:=ascii_characters[num]; END_FUNCTION

To import the zip files you have to right click on your src folder and chose import
click on archive, select the zip file and open.

This imports the iecst files to your src folder and you can use the functions.

Here's a little Program to get the digital inputs from the Beagle-IO board

BeagleBone IO cape
Code:
FUNCTION initGPIOs initGPIO('66'); initGPIO('67'); initGPIO('69'); initGPIO('68'); initGPIO('45'); initGPIO('44'); initGPIO('23'); initGPIO('26'); initGPIO('47'); initGPIO('46'); initGPIO('27'); initGPIO('65'); END_FUNCTION FUNCTION setGPIOsInput setGPIOinput('66'); setGPIOinput('67'); setGPIOinput('69'); setGPIOinput('68'); setGPIOinput('45'); setGPIOinput('44'); setGPIOinput('23'); setGPIOinput('26'); setGPIOinput('47'); setGPIOinput('46'); setGPIOinput('27'); setGPIOinput('65'); END_FUNCTION FUNCTION deinitGPIOs deinitGPIO('66'); deinitGPIO('67'); deinitGPIO('69'); deinitGPIO('68'); deinitGPIO('45'); deinitGPIO('44'); deinitGPIO('23'); deinitGPIO('26'); deinitGPIO('47'); deinitGPIO('46'); deinitGPIO('27'); deinitGPIO('65'); END_FUNCTION PROGRAM IOProgram VAR_EXTERNAL digitalInput01 :BOOL; digitalInput02 :BOOL; digitalInput03 :BOOL; digitalInput04 :BOOL; digitalInput05 :BOOL; digitalInput06 :BOOL; digitalInput07 :BOOL; digitalInput08 :BOOL; digitalInput09 :BOOL; digitalInput10 :BOOL; digitalInput11 :BOOL; digitalInput12 :BOOL; END_VAR VAR init :BOOL; run :BOOL; term :BOOL; END_VAR VAR FD_GPIO_66 :DINT; FD_GPIO_67 :DINT; FD_GPIO_69 :DINT; FD_GPIO_68 :DINT; FD_GPIO_45 :DINT; FD_GPIO_44 :DINT; FD_GPIO_23 :DINT; FD_GPIO_26 :DINT; FD_GPIO_47 :DINT; FD_GPIO_46 :DINT; FD_GPIO_27 :DINT; FD_GPIO_65 :DINT; read :DINT:=0; END_VAR RTSCycleInfo(Init=>init,Run=>run,Term=>term); IF init THEN Trace('Begin init'); initGPIOs(); setGPIOsInput(); FD_GPIO_66:=openGPIO('66', read); FD_GPIO_67:=openGPIO('67', read); FD_GPIO_69:=openGPIO('69', read); FD_GPIO_68:=openGPIO('68', read); FD_GPIO_45:=openGPIO('45', read); FD_GPIO_44:=openGPIO('44', read); FD_GPIO_23:=openGPIO('23', read); FD_GPIO_26:=openGPIO('26', read); FD_GPIO_47:=openGPIO('47', read); FD_GPIO_46:=openGPIO('46', read); FD_GPIO_27:=openGPIO('27', read); FD_GPIO_65:=openGPIO('65', read); Trace('Done init'); END_IF; IF run THEN digitalInput01:=readGPIO(FD_GPIO_66); digitalInput02:=readGPIO(FD_GPIO_67); digitalInput03:=readGPIO(FD_GPIO_69); digitalInput04:=readGPIO(FD_GPIO_68); digitalInput05:=readGPIO(FD_GPIO_45); digitalInput06:=readGPIO(FD_GPIO_44); digitalInput07:=readGPIO(FD_GPIO_23); digitalInput08:=readGPIO(FD_GPIO_26); digitalInput09:=readGPIO(FD_GPIO_47); digitalInput10:=readGPIO(FD_GPIO_46); digitalInput11:=readGPIO(FD_GPIO_27); digitalInput12:=readGPIO(FD_GPIO_65); END_IF; if term THEN Trace('Begin deinit'); System_close(FD_GPIO_66); System_close(FD_GPIO_67); System_close(FD_GPIO_69); System_close(FD_GPIO_68); System_close(FD_GPIO_45); System_close(FD_GPIO_44); System_close(FD_GPIO_23); System_close(FD_GPIO_26); System_close(FD_GPIO_47); System_close(FD_GPIO_46); System_close(FD_GPIO_27); System_close(FD_GPIO_65); deinitGPIOs(); Trace('Done deinit'); END_IF; END_PROGRAM

File Attachment:

File Name: gpio.zip
File Size:1 KB

File Attachment:

File Name: ascii.zip
File Size:1 KB
Attachments:
Last edit: 8 years 10 months ago by Karsten Hoffmann. Reason: to be more precise: the program example only reads the digital inputs on Beagle-IO board

Please Anmelden or Create an account to join the conversation.

Powered by Kunena Forum