commit c185c20a798d87ebe714531f4a94e78493e3bb7e Author: zlaxy Date: Sun Dec 23 18:53:54 2018 +0300 init diff --git a/salad/SCRBLUE.sh b/salad/SCRBLUE.sh new file mode 100755 index 0000000..5a1f5a2 --- /dev/null +++ b/salad/SCRBLUE.sh @@ -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 diff --git a/salad/ch1off.sh b/salad/ch1off.sh new file mode 100755 index 0000000..7b511bb --- /dev/null +++ b/salad/ch1off.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# channel 1 off +echo 1 >/sys/class/gpio/gpio36/value + diff --git a/salad/ch1on.sh b/salad/ch1on.sh new file mode 100755 index 0000000..b6e822c --- /dev/null +++ b/salad/ch1on.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# channel 1 on +echo 0 >/sys/class/gpio/gpio36/value + diff --git a/salad/ch2off.sh b/salad/ch2off.sh new file mode 100755 index 0000000..142fdce --- /dev/null +++ b/salad/ch2off.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# channel 2 off +echo 1 >/sys/class/gpio/gpio37/value + diff --git a/salad/ch2on.sh b/salad/ch2on.sh new file mode 100755 index 0000000..50b55fc --- /dev/null +++ b/salad/ch2on.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# channel 2 on +echo 0 >/sys/class/gpio/gpio37/value + diff --git a/salad/checkled.sh b/salad/checkled.sh new file mode 100755 index 0000000..e81d934 --- /dev/null +++ b/salad/checkled.sh @@ -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 diff --git a/salad/checkled2.sh b/salad/checkled2.sh new file mode 100755 index 0000000..017034e --- /dev/null +++ b/salad/checkled2.sh @@ -0,0 +1,2 @@ +#!/bin/bash +sudo -u root sh /salad/checkled.sh diff --git a/salad/chtemphum.sh b/salad/chtemphum.sh new file mode 100755 index 0000000..34c4131 --- /dev/null +++ b/salad/chtemphum.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 diff --git a/salad/dht22-pine64/Makefile b/salad/dht22-pine64/Makefile new file mode 100644 index 0000000..6282dec --- /dev/null +++ b/salad/dht22-pine64/Makefile @@ -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 diff --git a/salad/dht22-pine64/README.md b/salad/dht22-pine64/README.md new file mode 100644 index 0000000..e912381 --- /dev/null +++ b/salad/dht22-pine64/README.md @@ -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 -d 1000 +``` + +It will read DHT connected on value every 1000ms continuously. + +### Read specific value + +```bash +dht22 -p -s hum +dht22 -p -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 diff --git a/salad/dht22-pine64/c_gpio.c b/salad/dht22-pine64/c_gpio.c new file mode 100644 index 0000000..d933ba9 --- /dev/null +++ b/salad/dht22-pine64/c_gpio.c @@ -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 +#include +#include +#include +#include +#include +#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< +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); +} diff --git a/salad/dht22-pine64/c_gpio.h b/salad/dht22-pine64/c_gpio.h new file mode 100644 index 0000000..3c3433f --- /dev/null +++ b/salad/dht22-pine64/c_gpio.h @@ -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 diff --git a/salad/dht22-pine64/dht22 b/salad/dht22-pine64/dht22 new file mode 100755 index 0000000..8d3fb81 Binary files /dev/null and b/salad/dht22-pine64/dht22 differ diff --git a/salad/dht22-pine64/dht22.c b/salad/dht22-pine64/dht22.c new file mode 100644 index 0000000..588b50d --- /dev/null +++ b/salad/dht22-pine64/dht22.c @@ -0,0 +1,190 @@ +#include "wiringPi.h" +#include +#include +#include +#include +#include +#include +#include + +#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 ] [-r ] [-p ] [-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); +} diff --git a/salad/dht22-pine64/pine64-gpio-number.py b/salad/dht22-pine64/pine64-gpio-number.py new file mode 100644 index 0000000..2c87f2d --- /dev/null +++ b/salad/dht22-pine64/pine64-gpio-number.py @@ -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 " % sys.argv[0]) + sys.exit(1) + + print("%d" % convert(args[0])) \ No newline at end of file diff --git a/salad/dht22-pine64/wiringPi.c b/salad/dht22-pine64/wiringPi.c new file mode 100644 index 0000000..06167cf --- /dev/null +++ b/salad/dht22-pine64/wiringPi.c @@ -0,0 +1,103 @@ +// License MIT +// Compatibility layer done by Kamil Trzcinski + +#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) ; +} diff --git a/salad/dht22-pine64/wiringPi.h b/salad/dht22-pine64/wiringPi.h new file mode 100644 index 0000000..f83b4ad --- /dev/null +++ b/salad/dht22-pine64/wiringPi.h @@ -0,0 +1,19 @@ +// License MIT +// Compatibility layer done by Kamil Trzcinski + +#include "c_gpio.h" +#include +#include +#include +#include + +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); diff --git a/salad/gpioinit.sh b/salad/gpioinit.sh new file mode 100755 index 0000000..9559c65 --- /dev/null +++ b/salad/gpioinit.sh @@ -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 diff --git a/salad/screenshot.sh b/salad/screenshot.sh new file mode 100755 index 0000000..7262fd3 --- /dev/null +++ b/salad/screenshot.sh @@ -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