wiringPi is not working on 4th version of raspberry - raspberry-pi

I have an RPi4.
Based on this link I need to have a version 2.52 of gpio to work properly on this device.
I have done this:
# cd /tmp
# wget https://project-downloads.drogon.net/wiringpi-latest.deb
# sudo dpkg -i wiringpi-latest.deb
# gpio -v
gpio version: 2.46
Also, writing to GPIO is not working, all ports are logic 1 after booting.
And git.drogon.net is unavailable.
What can I do now if I need to compile a software which relies on this library..?
UPDATE
I have cloned this repository as stevieb recommended.
It also has a pull request for supporting PI4 boards.
However even after applying that patch I'm not able to control the output pins of the PI4:
First get the current states of the pins:
# gpio readall
+-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 1 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 1 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 1 | 15 || 16 | 1 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 1 | ALT0 | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 1 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 1 | 21 || 22 | 1 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 1 | 23 || 24 | 1 | ALT4 | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 1 | ALT5 | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 1 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 1 | 35 || 36 | 1 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 1 | 37 || 38 | 1 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 1 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
Then set pin7 to output and check the result:
# gpio mode 7 out
# gpio readall
+-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | OUT | 1 | 7 || 8 | 1 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 1 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 1 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 1 | 15 || 16 | 1 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 1 | ALT0 | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 1 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 1 | 21 || 22 | 1 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 1 | 23 || 24 | 1 | ALT4 | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 1 | ALT5 | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 1 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 1 | 35 || 36 | 1 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 1 | 37 || 38 | 1 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 1 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
Then write 0 to pin7 and check the result:
# gpio write 7 0
# gpio readall
+-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | OUT | 1 | 7 || 8 | 1 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 1 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 1 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 1 | 15 || 16 | 1 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 1 | ALT0 | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 1 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 1 | 21 || 22 | 1 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 1 | 23 || 24 | 1 | ALT4 | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 1 | ALT5 | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 1 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 1 | 35 || 36 | 1 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 1 | 37 || 38 | 1 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 1 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
As you can see every pin is at logic state 1. Measuring it with a voltage meter also confirms this.
Does anyone has any idea on how can I modify the wiringPi library to be able to set the output values correctly?
Thanks

Gordon abandoned the Open Source side of wiringPi some time ago, and removed access to it completely.
I have reached out several times to him since then and I've yet to receive a response. I even went as far as to request paid access to his changes so that my own wrapper software can continue to work.
Apparently, you'll have to get access to the older source code and modify it yourself. There's this 'fork' of v2.46 that you could base the changes off of.

Do what Gordon says in this link and it works again:
cd /tmp
wget https://project-downloads.drogon.net/wiringpi-latest.deb
sudo dpkg -i wiringpi-latest.deb

Version 2.52 of wiringPi for Raspberry 4 (and the equivalent GPIO shell commands) helps a lot, but it does not properly implement pullUpDnControl(). As a result input-pins cannot be set to use internal pull-up/pull-down resistors.
Tested with GPIO/BCM pin 26 using
sudo raspi-gpio get | grep "GPIO 26"
shell command.
Tried to set pull-up/pull-down using:
pullUpDnControl(26, PUD_DOWN);
and
pullUpDnControl(26, PUD_UP);
under
wiringPiSetupGpio();
wiringPi setup in C.
No change reported using the "raspi-gpio" shell command.
Since the issue was a static setup failure for me, rather than give up on wiringPi completely I implemented a kludge work around. Since I could not get the equivalent GPIO shell command to work (for the same reason (as it is part of the wiringPi suite)), but Python has been maintained and works, I imbedded equivalent Python pin setup code in C, and thought it might be useful for someone (to keep wiringPi working through Raspberry Pi 4).
For those who might find this useful, here's test code. A 3-LED Cylon. LEDs attached to (resistor-buffered (200OHM)) ground on one end and each to a different pin (16, 20, and 21) on the other). A switch to ground on one end and pin 26 on the other. When the switch is pressed, the Cylon display turns into a glare from all 3 LEDs until the switch is released. Pin numbers are in the BCM series, shown by the shell command "gpio readall".
/* 3-LED Cylon testbed. Embedded Python GPIO pin setup code
* as a workaround to wiringPi v2.52 pullUpDnControl() bug.
* Send setup code to Python's stdin, as a short-lived child process.
* Sends Python equivalent to pullUpDnControl(26, PUD_UP); keeping
* the pin number (26) as a C #define.
* Use as needed.
* Alen Shapiro June 2020
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPi.h>
/* on */
#define FIX_GPIO 1 // replace pullUpDnControl on Raspberry Pi 4. Use Python as GPIO in the shell fails too */
#define MICRO_SLEEP (100*1000) /* 100 microseconds */
#define LOW 0
#define HIGH 1
/* BCM: gpio -g // wPi // Phys: gpio -1 */
#define LED1 16 // 27 // 36
#define LED2 20 // 28 // 38
#define LED3 21 // 29 // 40
#define PRESS 26 // 25 // 37
#if defined(FIX_GPIO)
struct fixGPIO {
char *pyLine;
int pin;
} fixGPIO[] = { // feed a three-argument fprintf() to popen() (so #define pins can be passed (one per line))
{ "import RPi.GPIO as GPIO\n", 0},
{ "GPIO.setmode(GPIO.BCM)\n", 0},
{ "GPIO.setwarnings(False)\n", 0},
{ "GPIO.setup(%d, GPIO.IN, pull_up_down=GPIO.PUD_UP)\n", PRESS},
{ (char *)NULL, 0}
};
FILE *pythonStream;
#endif /* defined(FIX_GPIO) */
int
main(void) {
int i;
wiringPiSetupGpio();
//wiringPiSetupPhys();
printf("Raspberry Pi 4 - direct Cylon Test\n");
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(PRESS, INPUT);
#if defined(FIX_GPIO)
if((pythonStream=popen("python", "w")) == NULL) {
fprintf(stderr, "Can't run python to set pin mode\n");
exit(1);
}
for(i=0 ; fixGPIO[i].pyLine ; i++)
fprintf(pythonStream, fixGPIO[i].pyLine, fixGPIO[i].pin);
pclose(pythonStream);
#else /* defined(FIX_GPIO) */
pullUpDnControl(PRESS, PUD_UP); /* fails on RPi-4 (as does shell GPIO) */
#endif /* defined(FIX_GPIO) */
while(1) {
if(digitalRead(PRESS) == LOW) { // Glaring Cylon
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
usleep(MICRO_SLEEP);
}
else { // Happy Cylon
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
usleep(MICRO_SLEEP);
digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
//digitalWrite(LED3, LOW);
usleep(MICRO_SLEEP);
//digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, HIGH);
usleep(MICRO_SLEEP);
//digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, LOW);
usleep(MICRO_SLEEP);
}
}
}
Compiled with this Makefile:
CC=gcc
CLIBS= -lwiringPi
cylon: cylon.o
$(CC) -o cylon cylon.o $(CLIBS)
Here's a short live-photo of the Cylon testbed in action, ignore the Arduino which is just monitoring GPIO pin voltages (thanks John in Canada):
https://imgur.com/a/mlpr7Gr
ASIDE: Gordon... I'm sorry you've been put through the wringer by the lower end of a Gaussian Curve of people (just a tail, honest), and hope you're coming out the other end with sanity and health intact.

Although WiringPi is discontinued there was an unofficial patch (open-source is hard to kill, others will continue it).
Tested, and GPIO worked great on my RaspberryPi4 after applying that.
Patch:
diff -ruN wiringPi/wiringPi.c wiringPi/wiringPi.c
--- wiringPi/wiringPi.c
+++ wiringPi/wiringPi.c
## -215,6 +215,7 ## volatile unsigned int *_wiringPiTimerIrqRaw ;
#define GPIO_PERI_BASE_OLD 0x20000000
#define GPIO_PERI_BASE_NEW 0x3F000000
+#define GPIO_PERI_BASE_RP4 0xFE000000
static volatile unsigned int piGpioBase = 0 ;
## -547,6 +548,10 ## static uint8_t gpioToPUDCLK [] =
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
} ;
+#define PULLUPDN_OFFSET_2711_0 57
+#define PULLUPDN_OFFSET_2711_1 58
+#define PULLUPDN_OFFSET_2711_2 59
+#define PULLUPDN_OFFSET_2711_3 60
// gpioToPwmALT
// the ALT value to put a GPIO pin into PWM mode
## -814,7 +819,7 ## int piGpioLayout (void)
for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
*c = 0 ;
-
+
if (wiringPiDebug)
printf ("piGpioLayout: Revision string: %s\n", line) ;
## -883,7 +888,7 ## int piBoardRev (void)
* So the distinction between boards that I can see is:
*
* 0000 - Error
- * 0001 - Not used
+ * 0001 - Not used
*
* Original Pi boards:
* 0002 - Model B, Rev 1, 256MB, Egoman
## -955,6 +960,30 ## void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
+ char buffer[12] ;
+ const char *ranges_file = "/proc/device-tree/soc/ranges" ;
+ int info_fd = open(ranges_file, O_RDONLY) ;
+
+ if (info_fd < 0) {
+ fprintf(stderr, "cannot open: %s", ranges_file) ;
+ exit (EXIT_FAILURE) ;
+ }
+
+ ssize_t n = read(info_fd, buffer, sizeof(buffer)) ;
+ close(info_fd) ;
+
+ if (n < 8) {
+ fprintf(stderr, "cannot read base address: %s", ranges_file) ;
+ exit (EXIT_FAILURE) ;
+ }
+
+ uint32_t gpio_base = (buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7] << 0) ;
+
+ if (!gpio_base)
+ {
+ gpio_base = (buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11] << 0) ;
+ }
+
while (fgets (line, 120, cpuFd) != NULL)
if (strncmp (line, "Revision", 8) == 0)
break ;
## -968,7 +997,7 ## void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
*c = 0 ;
-
+
if (wiringPiDebug)
printf ("piBoardId: Revision string: %s\n", line) ;
## -1007,7 +1036,7 ## void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
bMfg = (revision & (0x0F << 16)) >> 16 ;
bMem = (revision & (0x07 << 20)) >> 20 ;
bWarranty = (revision & (0x03 << 24)) != 0 ;
-
+
*model = bType ;
*rev = bRev ;
*mem = bMem ;
## -1034,7 +1063,7 ## void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
// If longer than 4, we'll assume it's been overvolted
*warranty = strlen (c) > 4 ;
-
+
// Extract last 4 characters:
c = c + strlen (c) - 4 ;
## -1073,8 +1102,11 ## void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; }
}
+ if (gpio_base == GPIO_PERI_BASE_RP4) {
+ *model = PI_MODEL_4;
+ }
}
-
+
/*
## -1205,6 +1237,10 ## void pwmSetRange (unsigned int range)
void pwmSetClock (int divisor)
{
uint32_t pwm_control ;
+
+ if(piGpioBase == GPIO_PERI_BASE_RP4) {
+ divisor = 540*divisor/192;
+ }
divisor &= 4095 ;
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
## -1260,7 +1296,7 ## void gpioClockSet (int pin, int freq)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
-
+
divi = 19200000 / freq ;
divr = 19200000 % freq ;
divf = (int)((double)divr * 4096.0 / 19200000.0) ;
## -1504,11 +1540,31 ## void pullUpDnControl (int pin, int pud)
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
- *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ;
- *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
-
- *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
- *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
+ // Check GPIO register
+ int is2711 = *(gpio + PULLUPDN_OFFSET_2711_3) != 0x6770696f;
+ if(is2711) {
+ // Pi 4 Pull-up/down method
+ int pullreg = PULLUPDN_OFFSET_2711_0 + (pin >> 4);
+ int pullshift = (pin & 0xf) << 1;
+ unsigned int pullbits;
+ unsigned int pull = 0; // Turn PUD off by default
+ if (pud == PUD_UP) {
+ pull = 1;
+ } else if (pud == PUD_DOWN) {
+ pull = 2;
+ }
+ pullbits = *(gpio + pullreg);
+ pullbits &= ~(3 << pullshift);
+ pullbits |= (pull << pullshift);
+ *(gpio + pullreg) = pullbits;
+ } else {
+ // Legacy Pull-up/down method
+ *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ;
+ *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
+
+ *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
+ *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
+ }
}
else // Extension module
{
## -1680,7 +1736,7 ## void pwmWrite (int pin, int value)
/*
* analogRead:
- * Read the analog value of a given Pin.
+ * Read the analog value of a given Pin.
* There is no on-board Pi analog hardware,
* so this needs to go to a new node.
*********************************************************************************
## -1699,7 +1755,7 ## int analogRead (int pin)
/*
* analogWrite:
- * Write the analog value to the given Pin.
+ * Write the analog value to the given Pin.
* There is no on-board Pi analog hardware,
* so this needs to go to a new node.
*********************************************************************************
## -1748,7 +1804,7 ## void pwmToneWrite (int pin, int freq)
* Write an 8-bit byte to the first 8 GPIO pins - try to do it as
* fast as possible.
* However it still needs 2 operations to set the bits, so any external
- * hardware must not rely on seeing a change as there will be a change
+ * hardware must not rely on seeing a change as there will be a change
* to set the outputs bits to zero, then another change to set the 1's
* Reading is just bit fiddling.
* These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers
## -1804,7 +1860,7 ## unsigned int digitalReadByte (void)
data = (data << 1) | x ;
}
}
- else
+ else
{
raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins
for (pin = 0 ; pin < 8 ; ++pin)
## -1861,7 +1917,7 ## unsigned int digitalReadByte2 (void)
data = (data << 1) | x ;
}
}
- else
+ else
data = ((*(gpio + gpioToGPLEV [0])) >> 20) & 0xFF ; // First bank for these pins
return data ;
## -2265,6 +2321,9 ## int wiringPiSetup (void)
case PI_MODEL_ZERO: case PI_MODEL_ZERO_W:
piGpioBase = GPIO_PERI_BASE_OLD ;
break ;
+ case PI_MODEL_4:
+ piGpioBase = GPIO_PERI_BASE_RP4 ;
+ break ;
default:
piGpioBase = GPIO_PERI_BASE_NEW ;
## -2273,7 +2332,7 ## int wiringPiSetup (void)
// Open the master /dev/ memory control device
// Device strategy: December 2016:
-// Try /dev/mem. If that fails, then
+// Try /dev/mem. If that fails, then
// try /dev/gpiomem. If that fails then game over.
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
## -2311,13 +2370,13 ## int wiringPiSetup (void)
pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
if (pwm == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
-
+
// Clock control (needed for PWM)
clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ;
if (clk == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
-
+
// The drive pads
pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
## -2437,7 +2496,7 ## int wiringPiSetupSys (void)
// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later
-
+
for (pin = 0 ; pin < 64 ; ++pin)
{
sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
diff -ruN wiringPi/wiringPi.h wiringPi/wiringPi.h
--- wiringPi/wiringPi.h
+++ wiringPi/wiringPi.h
## -100,6 +100,7 ##
#define PI_MODEL_CM3 10
#define PI_MODEL_ZERO_W 12
#define PI_MODEL_3P 13
+#define PI_MODEL_4 14
#define PI_VERSION_1 0
#define PI_VERSION_1_1 1
Note that the patch should be executed inside of Wiring-Pi root (outside of it's wiringPi sub-directory).
Also, this is a copy of my other answer on RaspberryPi.StackExchange.com, and is not related to https://github.com/WiringPi/WiringPi (although, they are free to apply this, too).

Related

I2C is not working on raspberry pi 4 (but just sometimes)

My issue is that sometimes the i2c is not working on my raspberry pi 4. I have this error : unable to access '/dev/i2*': No such file or folder and Error: Could not open file /dev/i2c-1 or /dev/i2c/1': No such file or directory when executing i2cdetect -y 1.
I think I followed the installation instructions correctly :
I added this line in the /boot/config.txt file : dtparam=i2c1=on, dtparam=i2c_arm=on, dtoverlay=i2c-bcm2835, dtoverlay=i2c-dev
I have added i2c-dev and i2c-bcm2835 to the /etc/modules file
I find that when this error append, my gpio pins looks like this (gpio readall):
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | OUT | 1 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 1 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | OUT | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 0 | 31 || 32 | 1 | OUT | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | ALT4 | 1 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
And when everything is fine, it look like this :
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | OUT | 1 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 1 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | OUT | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 0 | 31 || 32 | 1 | OUT | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | ALT4 | 1 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
You can see the difference between pins 2 and 3 when i2c is working and when it's not. I forgot to mention that pins 2 and 3 are where my i2c is connected.
Is there any wait to make sure that the i2c is activated and is working when booting up ?
I don't know which instructions you followed, but you did way to much there. Now you have a set of conflicting driver modules enabled. All you need to have is
dtparam=i2c_arm=on
Remove everything else you have added to that file.
The modules should be present by default, so no need to copy anything around by hand. Or, next time, just use raspi-config to enable the default I2C bus, it will do the same.

partition by for iterval of 2 seconds

I have a DB with a field of timestamp,
I want to partition it for every 2 seconds (I know how to do it for 1 minute and one second)
this is an example of the DB:
create table data_t(id integer, time_t timestamp without time zone, data_t integer );
insert into data_t(id,time_t,data_t) values(1,'1999-01-08 04:05:06',248),
(2,'1999-01-08 04:05:06.03',45),
(3,'1999-01-08 04:05:06.035',98),
(4,'1999-01-08 04:05:06.9',57),
(5,'1999-01-08 04:05:07',86),
(6,'1999-01-08 04:05:08',84),
(7,'1999-01-08 04:05:08.5',832),
(8,'1999-01-08 04:05:08.7',86),
(9,'1999-01-08 04:05:08.9',863),
(10,'1999-01-08 04:05:9',866),
(11,'1999-01-08 04:05:10',862),
(12,'1999-01-08 04:05:10.5',863),
(13,'1999-01-08 04:05:10.55',826),
(14,'1999-01-08 04:05:11',816),
(15,'1999-01-08 04:05:11.7',186),
(16,'1999-01-08 04:05:12',862),
(17,'1999-01-08 04:05:12.5',826)
;
with t as (
select id,
time_t,
date_trunc('second', data_t.time_t) as time_t_1,
data_t
from data_t
), t1 as(
select *,
extract(hour from time_t_1) as h,
extract(minute from time_t_1) as m,
extract(second from time_t_1) as s
from t ) select *,
row_number() over(partition by h,m,s order by time_t_1) as t_sequence
from t1;
the output of this is:
| id | time_t | time_t_1 | data_t | h | m | s | t_sequence |
|----|--------------------------|----------------------|--------|---|---|----|------------|
| 1 | 1999-01-08T04:05:06Z | 1999-01-08T04:05:06Z | 248 | 4 | 5 | 6 | 1 |
| 2 | 1999-01-08T04:05:06.03Z | 1999-01-08T04:05:06Z | 45 | 4 | 5 | 6 | 2 |
| 3 | 1999-01-08T04:05:06.035Z | 1999-01-08T04:05:06Z | 98 | 4 | 5 | 6 | 3 |
| 4 | 1999-01-08T04:05:06.9Z | 1999-01-08T04:05:06Z | 57 | 4 | 5 | 6 | 4 |
| 5 | 1999-01-08T04:05:07Z | 1999-01-08T04:05:07Z | 86 | 4 | 5 | 7 | 1 |
| 6 | 1999-01-08T04:05:08Z | 1999-01-08T04:05:08Z | 84 | 4 | 5 | 8 | 1 |
| 7 | 1999-01-08T04:05:08.5Z | 1999-01-08T04:05:08Z | 832 | 4 | 5 | 8 | 2 |
| 8 | 1999-01-08T04:05:08.7Z | 1999-01-08T04:05:08Z | 86 | 4 | 5 | 8 | 3 |
| 9 | 1999-01-08T04:05:08.9Z | 1999-01-08T04:05:08Z | 863 | 4 | 5 | 8 | 4 |
| 10 | 1999-01-08T04:05:09Z | 1999-01-08T04:05:09Z | 866 | 4 | 5 | 9 | 1 |
| 11 | 1999-01-08T04:05:10Z | 1999-01-08T04:05:10Z | 862 | 4 | 5 | 10 | 1 |
| 12 | 1999-01-08T04:05:10.5Z | 1999-01-08T04:05:10Z | 863 | 4 | 5 | 10 | 2 |
| 13 | 1999-01-08T04:05:10.55Z | 1999-01-08T04:05:10Z | 826 | 4 | 5 | 10 | 3 |
| 14 | 1999-01-08T04:05:11Z | 1999-01-08T04:05:11Z | 816 | 4 | 5 | 11 | 1 |
| 15 | 1999-01-08T04:05:11.7Z | 1999-01-08T04:05:11Z | 186 | 4 | 5 | 11 | 2 |
| 16 | 1999-01-08T04:05:12Z | 1999-01-08T04:05:12Z | 862 | 4 | 5 | 12 | 1 |
| 17 | 1999-01-08T04:05:12.5Z | 1999-01-08T04:05:12Z | 826 | 4 | 5 | 12 | 2 |
as you can see the t_sequence start over every second but I want it to start over every 2 seconds,
is there a way to do it?
link for SQL fiddle with all the data

SQL query help: Calculate max of previous rows in the same query

I want to find for each row(where B = C = D = 1), the max of A among its previous rows(where B = C = D = 1) excluding its row after its ordered in chronological order.
Data in table looks like this:
+-------+-----+-----+-----+------+------+
|Grp id | B | C | D | A | time |
+-------+---- +-----+-----+------+------+
| 111 | 1 | 0 | 0 | 52 | t |
| 111 | 1 | 1 | 1 | 33 | t+1 |
| 111 | 0 | 1 | 0 | 34 | t+2 |
| 111 | 1 | 1 | 1 | 22 | t+3 |
| 111 | 0 | 0 | 0 | 12 | t+4 |
| 222 | 1 | 1 | 1 | 16 | t |
| 222 | 1 | 0 | 0 | 18 | t2+1 |
| 222 | 1 | 1 | 0 | 13 | t2+2 |
| 222 | 1 | 1 | 1 | 12 | t2+3 |
| 222 | 1 | 1 | 1 | 09 | t2+4 |
| 222 | 1 | 1 | 1 | 22 | t2+5 |
| 222 | 1 | 1 | 1 | 19 | t2+6 |
+-------+-----+-----+-----+------+------+
Above table is resultant of below query. Its obtained after left joins as below. Joins are necessary according to my project requirement.
SELECT Grp id, B, C, D, A, time, xxx
FROM "DCR" dcr
LEFT JOIN "DCM" dcm ON "Id" = dcm."DCRID"
LEFT JOIN "DC" dc ON dc."Id" = dcm."DCID"
ORDER BY dcr."time"
Result column needs to be evaluated based on formula I mentioned above. It needs to be calculated in same pass as we need to consider only its previous rows. Above xxx needs to be replaced by a subquery/statement to obtain the result.
And the result table should look like this:
+-------+-----+-----+-----+------+------+------+
|Grp id | B | C | D | A | time |Result|
+-------+---- +-----+-----+------+------+------+
| 111 | 1 | 0 | 0 | 52 | t | - |
| 111 | 1 | 1 | 1 | 33 | t+1 | - |
| 111 | 1 | 1 | 1 | 34 | t+2 | 33 |
| 111 | 1 | 1 | 1 | 22 | t+3 | 34 |
| 111 | 0 | 0 | 0 | 12 | t+4 | - |
| 222 | 1 | 1 | 1 | 16 | t | - |
| 222 | 1 | 0 | 0 | 18 | t2+1 | - |
| 222 | 1 | 1 | 0 | 13 | t2+2 | - |
| 222 | 1 | 1 | 1 | 12 | t2+3 | 16 |
| 222 | 1 | 1 | 1 | 09 | t2+4 | 16 |
| 222 | 1 | 1 | 1 | 22 | t2+5 | 16 |
| 222 | 1 | 1 | 1 | 19 | t2+6 | 22 |
+-------+-----+-----+-----+------+------+------+
The column could be computed with a window function:
CASE WHEN b = 1 AND c = 1 AND d = 1
THEN max(a) FILTER (WHERE b = 1 AND c = 1 AND d = 1)
OVER (PARTITION BY "grp id"
ORDER BY time
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
ELSE NULL
END
I didn't test it.

org mode - simplify table sum formula of multiple column

Now I need 5 formula for sum of each column, it works fine but I wish it can be simplified to one formula. Is it possible?
|----+----+----+-----+----|
| a | b | c | d | e |
|----+----+----+-----+----|
| 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 |
|----+----+----+-----+----|
| 34 | 38 | 42 | 160 | 50 |
|----+----+----+-----+----|
#+TBLFM: #>$5=vsum(#2$5..#-1$5)::#>$4=vsum(#2$1..#-1$4)::#>$3=vsum(#2$3..#-1$3)::#>$2=vsum(#2$2..#-1$2)::#>$1=vsum(#2$1..#-1$1)
This should work:
|----+----+----+----+----|
| a | b | c | d | e |
|----+----+----+----+----|
| 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 |
|----+----+----+----+----|
| 34 | 38 | 42 | 46 | 50 |
|----+----+----+----+----|
#+TBLFM: #>$1..#>$5=vsum(#2$0..#-1$0)
$0 on the RHS is the current column.

sparql getting all months between two dates SPARQL

I am working on a SPARQL query in TopBraid Composer to get the number of data quality rules in each month.
I have a Start Date and End Date, but I need to get all the months between the start date and end date so that I can get a count of the data quality rules applicable to that duration.
My current query and result is as follows-:
SELECT *
WHERE
{
?Rules CDE:Data_Quality_Rule_added_on ?Date1.
?Rules CDE:Data_Quality_Removed_On ?Date2
BIND(month(?Date1) AS ?Month1)
BIND(month(?Date2) AS ?Month2)
BIND(smf:duration("mon",?Date1,?Date2) AS ?dur)
}
LIMIT 5
| [Rules] | Date1 | Date2 | Month1 | Month2 | dur
| CDE:Data_Quality_Rule_13 | 2016-01-28 | 2016-09-15 | 01 | 09 | 8
| CDE:Data_Quality_Rule_16 | 2016-02-29 | 2016-08-08 | 02 | 08 | 5
| CDE:Data_Quality_Rule_18 | 2016-05-15 | 2016-10-31 | 05 | 10 | 6
| CDE:Data_Quality_Rule_4 | 2016-03-28 | 2016-07-02 | 03 | 07 | 3
| CDE:Data_Quality_Rule_5 | 2016-02-02 | 2016-06-06 | 02 | 06 | 4
I am able to get the start month,end month and the duration. But I would like to get all the months between the start month and end month in SPARQL. The end result is to get the month-wise count of the number of data qulaity rules based on the start and end date as follows-:
| Months | Number Of Data Quality Rules |
| 1 | 2
| 2 | 4
| 3 | 6
| 4 | 3
| 5 | 3
| 6 | 4
| 7 | 4
| 8 | 4
| 9 | 5
| 10 | 3
| 11 | 2
| 12 | 5
First, some data to work with that has some rules with begin and end dates:
#prefix : <urn:ex:>
#prefix xsd: <http://www.w3.org/2001/XMLSchema#>
:rule1 :begin "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime ;
:end "2011-06-10T14:45:13.815-05:00"^^xsd:dateTime .
:rule2 :begin "2011-04-10T14:45:13.815-05:00"^^xsd:dateTime ;
:end "2011-10-10T14:45:13.815-05:00"^^xsd:dateTime .
:rule3 :begin "2011-06-10T14:45:13.815-05:00"^^xsd:dateTime ;
:end "2011-11-10T14:45:13.815-05:00"^^xsd:dateTime .
Then you can write a query that gets the months in which each rule is active. IF you then group by the month, and count the number of rules, you get the number of rules active in each month:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?rule ?month {
#-- Specify the possible values for ?month
#-- in advance. These are just the numbers
#-- one through twelve.
values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }
#-- Get the begin and end dates of that
#-- you're interested in. The way you
#-- do this depends on the structure of
#-- your data, of course.
?rule :begin ?begin ; :end ?end .
#-- Then take only the values of ?month
#-- that are between the beginning month
#-- and the ending month.
filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
------------------
| rule | month |
==================
| :rule1 | 1 |
| :rule1 | 2 |
| :rule1 | 3 |
| :rule1 | 4 |
| :rule1 | 5 |
| :rule1 | 6 |
| :rule2 | 4 |
| :rule2 | 5 |
| :rule2 | 6 |
| :rule2 | 7 |
| :rule2 | 8 |
| :rule2 | 9 |
| :rule2 | 10 |
| :rule3 | 6 |
| :rule3 | 7 |
| :rule3 | 8 |
| :rule3 | 9 |
| :rule3 | 10 |
| :rule3 | 11 |
------------------
Now you can group those results by month, and then count the number of rules for each month:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?month (count(distinct ?rule) as ?numRules) where {
values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }
?rule :begin ?begin ; :end ?end .
filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
group by ?month
--------------------
| month | numRules |
====================
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 2 |
| 8 | 2 |
| 9 | 2 |
| 10 | 2 |
| 11 | 1 |
--------------------
That doesn't include month 12 in the result, because there were no rules active then. If you want all the months to be listed, you can make the rule matching part optional:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?month (count(distinct ?rule) as ?numRules) {
values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }
optional {
?rule :begin ?begin ; :end ?end .
filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
}
group by ?month
--------------------
| month | numRules |
====================
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 2 |
| 8 | 2 |
| 9 | 2 |
| 10 | 2 |
| 11 | 1 |
| 12 | 0 |
--------------------