init
This commit is contained in:
commit
c185c20a79
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
# files and dirs for backup:
|
||||
SAVEDIR=/salad/screenshots/
|
||||
DATETIME=`date "+%Y-%m-%d-%H-%M-%S"`
|
||||
ffmpeg -rtsp_transport tcp -i 'rtsp://ip.of.web.cam/user=admin&password=&channel=1&stream=0.sdp' -f image2 -vframes 1 -pix_fmt yuvj420p ${SAVEDIR}${DATETIME}.jpeg
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
# channel 1 off
|
||||
echo 1 >/sys/class/gpio/gpio36/value
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
# channel 1 on
|
||||
echo 0 >/sys/class/gpio/gpio36/value
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
# channel 2 off
|
||||
echo 1 >/sys/class/gpio/gpio37/value
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
# channel 2 on
|
||||
echo 0 >/sys/class/gpio/gpio37/value
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
HOUR=`date "+%H"`
|
||||
CH1STATUS=`gpio read 21`
|
||||
cd /salad
|
||||
if [ "$HOUR" = "10" ] || [ "$HOUR" = "11" ] || [ "$HOUR" = "12" ] || [ "$HOUR" = "13" ]
|
||||
then
|
||||
if [ "$CH1STATUS" = "0" ]; then
|
||||
echo $CH1STATUS
|
||||
sh ch1off.sh
|
||||
echo off
|
||||
fi
|
||||
else
|
||||
if [ "$CH1STATUS" = "1" ]; then
|
||||
echo $CH1STATUS
|
||||
sh ch1on.sh
|
||||
echo on
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
sudo -u root sh /salad/checkled.sh
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
cd /salad
|
||||
DATETIME=`date "+%Y-%m-%d-%H-%M"`
|
||||
HUM=`dht22 -p 38 -s hum`
|
||||
sleep 1
|
||||
TEMP=`dht22 -p 38 -s temp`
|
||||
echo "$DATETIME HUM = $HUM TEMP = $TEMP" >> SALAD_log.txt
|
|
@ -0,0 +1,7 @@
|
|||
dht22: *.c
|
||||
g++ -fpermissive -Wno-write-strings -o dht22 *.c
|
||||
|
||||
install: dht22
|
||||
sudo cp dht22 /usr/local/bin/
|
||||
sudo chown root /usr/local/bin/dht22
|
||||
sudo chmod u+s /usr/local/bin/dht22
|
|
@ -0,0 +1,57 @@
|
|||
## DHT11/22 for Pine A64
|
||||
|
||||
This is simple C application that reads DHT11/22 sensor using one wire protocol.
|
||||
|
||||
### Compile
|
||||
|
||||
Compile directly on Pine A64.
|
||||
|
||||
```bash
|
||||
apt-get install build-essential
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### Use it
|
||||
|
||||
Find a PINE GPIO number: http://joey.hazlett.us/pine64/pine64_pins.html
|
||||
|
||||
Execute in terminal:
|
||||
|
||||
```bash
|
||||
dht22 -p <pin-number> -d 1000
|
||||
```
|
||||
|
||||
It will read DHT connected on <pin-number> value every 1000ms continuously.
|
||||
|
||||
### Read specific value
|
||||
|
||||
```bash
|
||||
dht22 -p <pin-number> -s hum
|
||||
dht22 -p <pin-number> -s temp
|
||||
```
|
||||
|
||||
### Use with Home-Assistant
|
||||
|
||||
Add this to your configuration file:
|
||||
|
||||
```
|
||||
sensor:
|
||||
- platform: command_line
|
||||
name: office_room
|
||||
unit_of_measurement: "°C"
|
||||
command: "dht22 -r 10 -s temp -p 71"
|
||||
- platform: command_line
|
||||
name: office_room
|
||||
unit_of_measurement: "humidity"
|
||||
command: "dht22 -r 10 -s hum -p 71"
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
For controlling the GPIO's I used this RPi.GPIO-PineA64:
|
||||
https://github.com/swkim01/RPi.GPIO-PineA64/blob/master/source/c_gpio.c
|
||||
|
||||
## Author
|
||||
|
||||
Kamil Trzciński, ayufan@ayufan.eu
|
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
Copyright (c) 2012-2015 Ben Croston
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include "c_gpio.h"
|
||||
|
||||
#define BCM2708_PERI_BASE_DEFAULT 0x20000000
|
||||
#define BCM2709_PERI_BASE_DEFAULT 0x3f000000
|
||||
#define GPIO_BASE_OFFSET 0x200000
|
||||
#define FSEL_OFFSET 0 // 0x0000
|
||||
#define SET_OFFSET 7 // 0x001c / 4
|
||||
#define CLR_OFFSET 10 // 0x0028 / 4
|
||||
#define PINLEVEL_OFFSET 13 // 0x0034 / 4
|
||||
#define EVENT_DETECT_OFFSET 16 // 0x0040 / 4
|
||||
#define RISING_ED_OFFSET 19 // 0x004c / 4
|
||||
#define FALLING_ED_OFFSET 22 // 0x0058 / 4
|
||||
#define HIGH_DETECT_OFFSET 25 // 0x0064 / 4
|
||||
#define LOW_DETECT_OFFSET 28 // 0x0070 / 4
|
||||
#define PULLUPDN_OFFSET 37 // 0x0094 / 4
|
||||
#define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4
|
||||
|
||||
#define PAGE_SIZE (4*1024)
|
||||
#define BLOCK_SIZE (4*1024)
|
||||
|
||||
//
|
||||
// For Pine A64/A64+ Board
|
||||
//
|
||||
#define PINEA64_GPIO_MASK (0xFFFFFF80)
|
||||
#define SUNXI_GPIO_BASE 0x01C20000
|
||||
#define SUNXI_GPIO_REG_OFFSET 0x800
|
||||
#define PINEA64_GPIO_BASE (SUNXI_GPIO_BASE + SUNXI_GPIO_REG_OFFSET)
|
||||
#define SUNXI_CFG_OFFSET 0x00
|
||||
#define SUNXI_DATA_OFFSET 0x10
|
||||
#define SUNXI_PUD_OFFSET 0x1C
|
||||
#define SUNXI_BANK_SIZE 0x24
|
||||
|
||||
#define MAP_SIZE (4096*2)
|
||||
#define MAP_MASK (MAP_SIZE - 1)
|
||||
|
||||
typedef struct sunxi_gpio {
|
||||
unsigned int CFG[4];
|
||||
unsigned int DAT;
|
||||
unsigned int DRV[2];
|
||||
unsigned int PULL[2];
|
||||
} sunxi_gpio_t;
|
||||
|
||||
/* gpio interrupt control */
|
||||
typedef struct sunxi_gpio_int {
|
||||
unsigned int CFG[3];
|
||||
unsigned int CTL;
|
||||
unsigned int STA;
|
||||
unsigned int DEB;
|
||||
} sunxi_gpio_int_t;
|
||||
|
||||
typedef struct sunxi_gpio_reg {
|
||||
struct sunxi_gpio gpio_bank[9];
|
||||
unsigned char res[0xbc];
|
||||
struct sunxi_gpio_int gpio_int;
|
||||
} sunxi_gpio_reg_t;
|
||||
|
||||
#define GPIO_BANK(pin) ((pin) >> 5)
|
||||
#define GPIO_NUM(pin) ((pin) & 0x1F)
|
||||
|
||||
#define GPIO_CFG_INDEX(pin) (((pin) & 0x1F) >> 3)
|
||||
#define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1F) & 0x7) << 2)
|
||||
|
||||
#define GPIO_PUL_INDEX(pin) (((pin) & 0x1F )>> 4)
|
||||
#define GPIO_PUL_OFFSET(pin) (((pin) & 0x0F) << 1)
|
||||
|
||||
int pinea64_found = 1;
|
||||
|
||||
static volatile uint32_t *pio_map;
|
||||
// end of Pine A64/A64+
|
||||
|
||||
static volatile uint32_t *gpio_map;
|
||||
|
||||
void short_wait(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<150; i++) { // wait 150 cycles
|
||||
asm volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
int setup(void)
|
||||
{
|
||||
int mem_fd;
|
||||
uint8_t *gpio_mem;
|
||||
uint32_t peri_base;
|
||||
uint32_t gpio_base;
|
||||
unsigned char buf[4];
|
||||
FILE *fp;
|
||||
char buffer[1024];
|
||||
char hardware[1024];
|
||||
int found = 0;
|
||||
|
||||
pinea64_found = 1;
|
||||
|
||||
if ( !pinea64_found ) {
|
||||
// try /dev/gpiomem first - this does not require root privs
|
||||
if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0)
|
||||
{
|
||||
gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0);
|
||||
if ((uint32_t)gpio_map < 0) {
|
||||
return SETUP_MMAP_FAIL;
|
||||
} else {
|
||||
return SETUP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// revert to /dev/mem method - requires root
|
||||
|
||||
// determine peri_base
|
||||
if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL) {
|
||||
// get peri base from device tree
|
||||
fseek(fp, 4, SEEK_SET);
|
||||
if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
|
||||
peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
// guess peri base based on /proc/cpuinfo hardware field
|
||||
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
|
||||
return SETUP_CPUINFO_FAIL;
|
||||
|
||||
while(!feof(fp) && !found) {
|
||||
fgets(buffer, sizeof(buffer), fp);
|
||||
sscanf(buffer, "Hardware : %s", hardware);
|
||||
if (strcmp(hardware, "BCM2708") == 0 || strcmp(hardware, "BCM2835") == 0) {
|
||||
// pi 1 hardware
|
||||
peri_base = BCM2708_PERI_BASE_DEFAULT;
|
||||
found = 1;
|
||||
} else if (strcmp(hardware, "BCM2709") == 0 || strcmp(hardware, "BCM2836") == 0) {
|
||||
// pi 2 hardware
|
||||
peri_base = BCM2709_PERI_BASE_DEFAULT;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
if (!found)
|
||||
return SETUP_NOT_RPI_FAIL;
|
||||
}
|
||||
|
||||
gpio_base = peri_base + GPIO_BASE_OFFSET;
|
||||
}
|
||||
|
||||
// mmap the GPIO memory registers
|
||||
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
|
||||
return SETUP_DEVMEM_FAIL;
|
||||
|
||||
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
|
||||
return SETUP_MALLOC_FAIL;
|
||||
|
||||
if ((uint32_t)gpio_mem % PAGE_SIZE)
|
||||
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
|
||||
|
||||
if ( pinea64_found ) {
|
||||
gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, SUNXI_GPIO_BASE);
|
||||
pio_map = gpio_map + (SUNXI_GPIO_REG_OFFSET>>2);
|
||||
} else {
|
||||
gpio_map = (uint32_t *)mmap( (void *)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base);
|
||||
}
|
||||
|
||||
if ((uint32_t)gpio_map < 0)
|
||||
return SETUP_MMAP_FAIL;
|
||||
|
||||
return SETUP_OK;
|
||||
}
|
||||
|
||||
void clear_event_detect(int gpio)
|
||||
{
|
||||
if ( !pinea64_found ) {
|
||||
int offset = EVENT_DETECT_OFFSET + (gpio/32);
|
||||
int shift = (gpio%32);
|
||||
|
||||
*(gpio_map+offset) |= (1 << shift);
|
||||
short_wait();
|
||||
*(gpio_map+offset) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int eventdetected(int gpio)
|
||||
{
|
||||
if ( !pinea64_found ) {
|
||||
int offset, value, bit;
|
||||
|
||||
offset = EVENT_DETECT_OFFSET + (gpio/32);
|
||||
bit = (1 << (gpio%32));
|
||||
value = *(gpio_map+offset) & bit;
|
||||
if (value)
|
||||
clear_event_detect(gpio);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
void set_rising_event(int gpio, int enable)
|
||||
{
|
||||
if ( !pinea64_found ) {
|
||||
int offset = RISING_ED_OFFSET + (gpio/32);
|
||||
int shift = (gpio%32);
|
||||
|
||||
if (enable)
|
||||
*(gpio_map+offset) |= 1 << shift;
|
||||
else
|
||||
*(gpio_map+offset) &= ~(1 << shift);
|
||||
clear_event_detect(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
void set_falling_event(int gpio, int enable)
|
||||
{
|
||||
if ( !pinea64_found ) {
|
||||
int offset = FALLING_ED_OFFSET + (gpio/32);
|
||||
int shift = (gpio%32);
|
||||
|
||||
if (enable) {
|
||||
*(gpio_map+offset) |= (1 << shift);
|
||||
*(gpio_map+offset) = (1 << shift);
|
||||
} else {
|
||||
*(gpio_map+offset) &= ~(1 << shift);
|
||||
}
|
||||
clear_event_detect(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
void set_high_event(int gpio, int enable)
|
||||
{
|
||||
if ( !pinea64_found ) {
|
||||
int offset = HIGH_DETECT_OFFSET + (gpio/32);
|
||||
int shift = (gpio%32);
|
||||
|
||||
if (enable)
|
||||
*(gpio_map+offset) |= (1 << shift);
|
||||
else
|
||||
*(gpio_map+offset) &= ~(1 << shift);
|
||||
clear_event_detect(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
void set_low_event(int gpio, int enable)
|
||||
{
|
||||
if ( !pinea64_found ) {
|
||||
int offset = LOW_DETECT_OFFSET + (gpio/32);
|
||||
int shift = (gpio%32);
|
||||
|
||||
if (enable)
|
||||
*(gpio_map+offset) |= 1 << shift;
|
||||
else
|
||||
*(gpio_map+offset) &= ~(1 << shift);
|
||||
clear_event_detect(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sunxi_readl(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
uint32_t mmap_base = (uint32_t)addr & (~MAP_MASK);
|
||||
uint32_t mmap_seek = ((uint32_t)addr - mmap_base) >> 2;
|
||||
val = *(gpio_map + mmap_seek);
|
||||
return val;
|
||||
}
|
||||
|
||||
void sunxi_writel(volatile uint32_t *addr, uint32_t val)
|
||||
{
|
||||
uint32_t mmap_base = (uint32_t)addr & (~MAP_MASK);
|
||||
uint32_t mmap_seek =( (uint32_t)addr - mmap_base) >> 2;
|
||||
*(gpio_map + mmap_seek) = val;
|
||||
}
|
||||
|
||||
void set_pullupdn(int gpio, int pud)
|
||||
{
|
||||
if ( pinea64_found ) {
|
||||
uint32_t regval = 0;
|
||||
int bank = GPIO_BANK(gpio); //gpio >> 5
|
||||
int index = GPIO_PUL_INDEX(gpio); // (gpio & 0x1f) >> 4
|
||||
int offset = GPIO_PUL_OFFSET(gpio); // (gpio) & 0x0F) << 1
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
|
||||
|
||||
regval = *(&pio->PULL[0] + index);
|
||||
regval &= ~(3 << offset);
|
||||
regval |= pud << offset;
|
||||
*(&pio->PULL[0] + index) = regval;
|
||||
} else {
|
||||
int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
|
||||
int shift = (gpio%32);
|
||||
|
||||
if (pud == PUD_DOWN)
|
||||
*(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN;
|
||||
else if (pud == PUD_UP)
|
||||
*(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
|
||||
else // pud == PUD_OFF
|
||||
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
|
||||
|
||||
short_wait();
|
||||
*(gpio_map+clk_offset) = 1 << shift;
|
||||
short_wait();
|
||||
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
|
||||
*(gpio_map+clk_offset) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_gpio(int gpio, int direction, int pud)
|
||||
{
|
||||
if ( pinea64_found ) {
|
||||
uint32_t regval = 0;
|
||||
int bank = GPIO_BANK(gpio); //gpio >> 5
|
||||
int index = GPIO_CFG_INDEX(gpio); // (gpio & 0x1F) >> 3
|
||||
int offset = GPIO_CFG_OFFSET(gpio); // ((gpio & 0x1F) & 0x7) << 2
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
|
||||
|
||||
set_pullupdn(gpio, pud);
|
||||
|
||||
regval = *(&pio->CFG[0] + index);
|
||||
regval &= ~(0x7 << offset); // 0xf?
|
||||
if (INPUT == direction) {
|
||||
*(&pio->CFG[0] + index) = regval;
|
||||
} else if (OUTPUT == direction) {
|
||||
regval |= (1 << offset);
|
||||
*(&pio->CFG[0] + index) = regval;
|
||||
} else {
|
||||
printf("line:%dgpio number error\n",__LINE__);
|
||||
}
|
||||
} else {
|
||||
int offset = FSEL_OFFSET + (gpio/10);
|
||||
int shift = (gpio%10)*3;
|
||||
|
||||
set_pullupdn(gpio, pud);
|
||||
if (direction == OUTPUT)
|
||||
*(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift)) | (1<<shift);
|
||||
else // direction == INPUT
|
||||
*(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift));
|
||||
}
|
||||
}
|
||||
|
||||
// Contribution by Eric Ptak <trouch@trouch.com>
|
||||
int gpio_function(int gpio)
|
||||
{
|
||||
if ( pinea64_found ) {
|
||||
uint32_t regval = 0;
|
||||
int bank = GPIO_BANK(gpio); //gpio >> 5
|
||||
int index = GPIO_CFG_INDEX(gpio); // (gpio & 0x1F) >> 3
|
||||
int offset = GPIO_CFG_OFFSET(gpio); // ((gpio & 0x1F) & 0x7) << 2
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
|
||||
|
||||
regval = *(&pio->CFG[0] + index);
|
||||
regval >>= offset;
|
||||
regval &= 7;
|
||||
return regval; // 0=input, 1=output, 4=alt0
|
||||
} else {
|
||||
int offset = FSEL_OFFSET + (gpio/10);
|
||||
int shift = (gpio%10)*3;
|
||||
int value = *(gpio_map+offset);
|
||||
value >>= shift;
|
||||
value &= 7;
|
||||
return value; // 0=input, 1=output, 4=alt0
|
||||
}
|
||||
}
|
||||
|
||||
void output_gpio(int gpio, int value)
|
||||
{
|
||||
if ( pinea64_found ) {
|
||||
int bank = GPIO_BANK(gpio); //gpio >> 5
|
||||
int num = GPIO_NUM(gpio); // gpio & 0x1F
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
|
||||
|
||||
if (value == 0)
|
||||
*(&pio->DAT) &= ~(1 << num);
|
||||
else
|
||||
*(&pio->DAT) |= (1 << num);
|
||||
} else {
|
||||
int offset, shift;
|
||||
|
||||
if (value) // value == HIGH
|
||||
offset = SET_OFFSET + (gpio/32);
|
||||
else // value == LOW
|
||||
offset = CLR_OFFSET + (gpio/32);
|
||||
|
||||
shift = (gpio%32);
|
||||
|
||||
*(gpio_map+offset) = 1 << shift;
|
||||
}
|
||||
}
|
||||
|
||||
int input_gpio(int gpio)
|
||||
{
|
||||
if ( pinea64_found ) {
|
||||
uint32_t regval = 0;
|
||||
int bank = GPIO_BANK(gpio); //gpio >> 5
|
||||
int num = GPIO_NUM(gpio); // gpio & 0x1F
|
||||
|
||||
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
|
||||
|
||||
regval = *(&pio->DAT);
|
||||
regval = regval >> num;
|
||||
regval &= 1;
|
||||
return regval;
|
||||
} else {
|
||||
int offset, value, mask;
|
||||
|
||||
offset = PINLEVEL_OFFSET + (gpio/32);
|
||||
mask = (1 << gpio%32);
|
||||
value = *(gpio_map+offset) & mask;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup(void)
|
||||
{
|
||||
munmap((void *)gpio_map, BLOCK_SIZE);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright (c) 2012-2015 Ben Croston
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
int setup(void);
|
||||
void setup_gpio(int gpio, int direction, int pud);
|
||||
int gpio_function(int gpio);
|
||||
void output_gpio(int gpio, int value);
|
||||
int input_gpio(int gpio);
|
||||
void set_rising_event(int gpio, int enable);
|
||||
void set_falling_event(int gpio, int enable);
|
||||
void set_high_event(int gpio, int enable);
|
||||
void set_low_event(int gpio, int enable);
|
||||
int eventdetected(int gpio);
|
||||
void cleanup(void);
|
||||
|
||||
#define SETUP_OK 0
|
||||
#define SETUP_DEVMEM_FAIL 1
|
||||
#define SETUP_MALLOC_FAIL 2
|
||||
#define SETUP_MMAP_FAIL 3
|
||||
#define SETUP_CPUINFO_FAIL 4
|
||||
#define SETUP_NOT_RPI_FAIL 5
|
||||
|
||||
#define INPUT 1 // is really 0 for control register!
|
||||
#define OUTPUT 0 // is really 1 for control register!
|
||||
#define ALT0 4
|
||||
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
|
||||
#define PUD_OFF 0
|
||||
#define PUD_UP 1
|
||||
#define PUD_DOWN 2
|
Binary file not shown.
|
@ -0,0 +1,190 @@
|
|||
#include "wiringPi.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/resource.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_TIMINGS 86
|
||||
|
||||
int DHT_PIN = 0;
|
||||
|
||||
int read_dht_data(float *h, float *t)
|
||||
{
|
||||
uint8_t j = 0, i;
|
||||
int data[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
pinMode(DHT_PIN, OUTPUT);
|
||||
digitalWrite(DHT_PIN, LOW);
|
||||
delay(18);
|
||||
digitalWrite(DHT_PIN, HIGH);
|
||||
delayMicroseconds(10);
|
||||
|
||||
pinMode(DHT_PIN, INPUT);
|
||||
|
||||
uint8_t laststate = HIGH;
|
||||
unsigned int lasttime = micros();
|
||||
|
||||
for(i = 0; i < MAX_TIMINGS; i++) {
|
||||
int state;
|
||||
unsigned int current;
|
||||
|
||||
while (true) {
|
||||
state = digitalRead(DHT_PIN);
|
||||
current = micros();
|
||||
if (current - lasttime > 200) {
|
||||
goto finish;
|
||||
}
|
||||
if (laststate != state) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore first 3 transitions */
|
||||
if ((i >= 4) && (i % 2 == 0)) {
|
||||
/* shove each bit into the storage bytes */
|
||||
data[j / 8] <<= 1;
|
||||
if ((current - lasttime) > 60)
|
||||
data[j / 8] |= 1;
|
||||
j++;
|
||||
}
|
||||
|
||||
laststate = state;
|
||||
lasttime = current;
|
||||
}
|
||||
|
||||
finish:
|
||||
|
||||
if (j < 40) {
|
||||
fprintf(stderr, "Not enough bits: %d\n", j);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
|
||||
fprintf(stderr, "Invalid CRC\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (h) {
|
||||
*h = (float)((data[0] << 8) + data[1]) / 10;
|
||||
if (*h > 100) {
|
||||
*h = data[0]; // for DHT11
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
*t = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
|
||||
if (*t > 125) {
|
||||
*t = data[2]; // for DHT11
|
||||
}
|
||||
if (data[2] & 0x80) {
|
||||
*t = -*t;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setprio() {
|
||||
id_t pid = getpid();
|
||||
int ret = setpriority(PRIO_PROCESS, pid, 10000);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to set prio: %d\n", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void usage(const char *cmd) {
|
||||
fprintf(stderr, "Usage: %s [-d <delaymsec>] [-r <retry>] [-p <pin>] [-s all|hum|temp]\n", cmd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int delaymsec = 0;
|
||||
int retry = 2;
|
||||
int whattoshow = 0;
|
||||
|
||||
while (true) {
|
||||
switch (getopt(argc, argv, "d:r:p:s:")) {
|
||||
case -1:
|
||||
goto done;
|
||||
|
||||
case 'd':
|
||||
delaymsec = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
retry = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
DHT_PIN = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (!strcmp(optarg, "all")) {
|
||||
whattoshow = 0;
|
||||
} else if (!strcmp(optarg, "hum")) {
|
||||
whattoshow = 1;
|
||||
} else if (!strcmp(optarg, "temp")) {
|
||||
whattoshow = 2;
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* '?' */
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (DHT_PIN <= 0) {
|
||||
fprintf(stderr, "Missing DHT PIN. Go to: http://joey.hazlett.us/pine64/pine64_pins.html\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (wiringPiSetup()) {
|
||||
fprintf(stderr, "Failed to configure GPIO\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
setprio();
|
||||
|
||||
while (1) {
|
||||
float h = 0, c = 0;
|
||||
|
||||
for(int i = 0; i <= retry; ++i) {
|
||||
if(read_dht_data(&h, &c) == 0) {
|
||||
switch(whattoshow) {
|
||||
case 0:
|
||||
printf("Humidity: %.1f %%\n", h);
|
||||
printf("Temperature: %.1f *C\n", c);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
printf("%.1f\n", h);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
printf("%.1f\n", c);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(delaymsec > 0) {
|
||||
delay(delaymsec);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import string
|
||||
|
||||
def convert(value):
|
||||
value = value.upper()
|
||||
alp = value[1]
|
||||
idx = string.ascii_uppercase.index(alp)
|
||||
num = int(value[2:], 10)
|
||||
res = idx * 32 + num
|
||||
return res
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = sys.argv[1:]
|
||||
if not args:
|
||||
print("Usage: %s <pin>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
print("%d" % convert(args[0]))
|
|
@ -0,0 +1,103 @@
|
|||
// License MIT
|
||||
// Compatibility layer done by Kamil Trzcinski <ayufan@ayufan.eu>
|
||||
|
||||
#include "wiringPi.h"
|
||||
|
||||
static uint64_t epochMilli, epochMicro;
|
||||
|
||||
int wiringPiSetup()
|
||||
{
|
||||
initialiseEpoch();
|
||||
return setup();
|
||||
}
|
||||
|
||||
int digitalRead(int gpio)
|
||||
{
|
||||
return input_gpio(gpio);
|
||||
}
|
||||
|
||||
void digitalWrite(int gpio, int value)
|
||||
{
|
||||
output_gpio(gpio, value);
|
||||
}
|
||||
|
||||
void pinMode(int gpio, int direction)
|
||||
{
|
||||
setup_gpio(gpio, direction, PUD_UP);
|
||||
}
|
||||
|
||||
//
|
||||
// The functions belowe are copied from wiringPi
|
||||
//
|
||||
|
||||
void initialiseEpoch (void)
|
||||
{
|
||||
struct timeval tv ;
|
||||
|
||||
gettimeofday (&tv, NULL) ;
|
||||
epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ;
|
||||
epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ;
|
||||
}
|
||||
|
||||
void delayMicrosecondsHard (unsigned int howLong)
|
||||
{
|
||||
struct timeval tNow, tLong, tEnd ;
|
||||
|
||||
gettimeofday (&tNow, NULL) ;
|
||||
tLong.tv_sec = howLong / 1000000 ;
|
||||
tLong.tv_usec = howLong % 1000000 ;
|
||||
timeradd (&tNow, &tLong, &tEnd) ;
|
||||
|
||||
while (timercmp (&tNow, &tEnd, <))
|
||||
gettimeofday (&tNow, NULL) ;
|
||||
}
|
||||
|
||||
void delayMicroseconds (unsigned int howLong)
|
||||
{
|
||||
struct timespec sleeper ;
|
||||
unsigned int uSecs = howLong % 1000000 ;
|
||||
unsigned int wSecs = howLong / 1000000 ;
|
||||
|
||||
/**/ if (howLong == 0)
|
||||
return ;
|
||||
else if (howLong < 100)
|
||||
delayMicrosecondsHard (howLong) ;
|
||||
else
|
||||
{
|
||||
sleeper.tv_sec = wSecs ;
|
||||
sleeper.tv_nsec = (long)(uSecs * 1000L) ;
|
||||
nanosleep (&sleeper, NULL) ;
|
||||
}
|
||||
}
|
||||
|
||||
void delay (unsigned int howLong)
|
||||
{
|
||||
struct timespec sleeper, dummy ;
|
||||
|
||||
sleeper.tv_sec = (time_t)(howLong / 1000) ;
|
||||
sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
|
||||
|
||||
nanosleep (&sleeper, &dummy) ;
|
||||
}
|
||||
|
||||
unsigned int millis (void)
|
||||
{
|
||||
struct timeval tv ;
|
||||
uint64_t now ;
|
||||
|
||||
gettimeofday (&tv, NULL) ;
|
||||
now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ;
|
||||
|
||||
return (uint32_t)(now - epochMilli) ;
|
||||
}
|
||||
|
||||
unsigned int micros (void)
|
||||
{
|
||||
struct timeval tv ;
|
||||
uint64_t now ;
|
||||
|
||||
gettimeofday (&tv, NULL) ;
|
||||
now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ;
|
||||
|
||||
return (uint32_t)(now - epochMicro) ;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// License MIT
|
||||
// Compatibility layer done by Kamil Trzcinski <ayufan@ayufan.eu>
|
||||
|
||||
#include "c_gpio.h"
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
int wiringPiSetup();
|
||||
int digitalRead(int gpio);
|
||||
void digitalWrite(int gpio, int value);
|
||||
void pinMode(int gpio, int direction);
|
||||
void initialiseEpoch (void);
|
||||
void delayMicrosecondsHard (unsigned int howLong);
|
||||
void delayMicroseconds (unsigned int howLong);
|
||||
void delay (unsigned int howLong);
|
||||
unsigned int millis (void);
|
||||
unsigned int micros (void);
|
|
@ -0,0 +1,33 @@
|
|||
#! /bin/sh
|
||||
|
||||
ntpdate -q 0.rhel.pool.ntp.org
|
||||
|
||||
echo 361 >/sys/class/gpio/export
|
||||
echo out >/sys/class/gpio/gpio361/direction
|
||||
echo 1 >/sys/class/gpio/gpio361/value
|
||||
|
||||
echo 68 >/sys/class/gpio/export
|
||||
echo out >/sys/class/gpio/gpio68/direction
|
||||
echo 1 >/sys/class/gpio/gpio68/value
|
||||
|
||||
echo 36 >/sys/class/gpio/export
|
||||
echo out >/sys/class/gpio/gpio36/direction
|
||||
echo 1 >/sys/class/gpio/gpio36/value
|
||||
|
||||
echo 37 >/sys/class/gpio/export
|
||||
echo out >/sys/class/gpio/gpio37/direction
|
||||
echo 1 >/sys/class/gpio/gpio37/value
|
||||
|
||||
echo 39 >/sys/class/gpio/export
|
||||
echo out >/sys/class/gpio/gpio39/direction
|
||||
echo 1 >/sys/class/gpio/gpio39/value
|
||||
|
||||
echo 101 >/sys/class/gpio/export
|
||||
echo out >/sys/class/gpio/gpio101/direction
|
||||
echo 1 >/sys/class/gpio/gpio101/value
|
||||
|
||||
echo 38 >/sys/class/gpio/export
|
||||
echo in >/sys/class/gpio/gpio38/direction
|
||||
|
||||
sleep 120
|
||||
ntpdate -q 0.rhel.pool.ntp.org
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
# 10-15sec for photo
|
||||
SAVEDIR=/salad/screenshots/
|
||||
DATETIME=`date "+%Y-%m-%d-%H-%M-%S"`
|
||||
CH1STATUS=`gpio read 21`
|
||||
cd /salad
|
||||
./ch2on.sh
|
||||
sleep 0.5
|
||||
./ch1off.sh
|
||||
sleep 9
|
||||
ffmpeg -rtsp_transport tcp -i 'rtsp://ip.of.web.cam/user=admin&password=&channel=1&stream=0.sdp' -f image2 -vframes 1 -pix_fmt yuvj420p ${SAVEDIR}${DATETIME}.jpeg
|
||||
if [ "$CH1STATUS" = 0 ]
|
||||
then
|
||||
./ch1on.sh
|
||||
fi
|
||||
sleep 0.1
|
||||
./ch2off.sh
|
Loading…
Reference in New Issue