Monthly Archives: February 2020

VoCore2: touch screen for HMI ready

Finally I make this:

VoCore2+Qt+Touch

It works very smooth, just like smart phone. And color is very well too. 🙂 I really like this small device, I guess it should be the lowest cost WVGA(800×480) UI solution or HMI solution. 1K units should be less than 10USD, so with VoCore2, the full solution cost can be less than 20USD.

Now I am busy on doing the final debug and fix. Hopefully in next month, I can get first batch of the production and put on vocore.io.

Because currently I am updating the fully screen every frame, so its FPS is pretty low, only 30fps, but I find a way to update the screen partially, so once I finish the next patch, the screen will reach 60fps, can be run on VoCore, Android smart phone and Windows computer as an extend screen.

Qt recently public MCU1.0, running on a very expansive platform over 30USD with low speed CPU and only 1MB~4MB memory. I guess it will be perfect with VoCore and this screen. I will be the first guy port it. :p

VoCore2: Temperature and Humidity Sensor(I2C)

i2c-tools is not that easy to use in some situation. Recently I need to make sure my room is wet enough to kill virus, so I develop a simple tool based on SHT20 — a temperature and humidity sensor, but I find I can not use i2c-tools to test SHT20 I2C bus, it missed some key features.

I have to spend couple of hours write another one.

usage: i2ctest [dev path] [address] [r/w] [length/data]


example:

show device on i2c-0:
	i2ctest /dev/i2c-0

read 3 byte from i2c-0, address 0x40:
	i2ctest /dev/i2c-0 0x40 r 3

write 2 byte(0xe2 0x88) to i2c-0, address 0x21:
	i2ctest /dev/i2c-0 0x21 w '0xe2 0x88'

For my usage, query i2c devices:

root@OpenWrt:/tmp# i2ctest /dev/i2c-0 
0x10: BUSY
0x40: READY

0x10 is BUSY because the ES8388 driver already taken the address.

0x40 is the SHT20 address. From SHT20 datasheet, write 0xF3 first then read 3 bytes from it, we will get temperature.

root@OpenWrt:/tmp# i2ctest /dev/i2c-0 0x40 w 0xf3
write: 1 byte(s)
root@OpenWrt:/tmp# i2ctest /dev/i2c-0 0x40 r 3
00000000: 64 98 56                                            d.V

Calculate from the data: T = 0x6498 * 175.72 / 65536 – 46.85 = 22.198C

Here is the source code for i2ctest.c

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/i2c.h>
#include <linux/i2c-dev.h>


#define min(a, b)	((a) < (b) ? (a) : (b))

void hex_print(const unsigned char* s, int size, FILE *fp)
{
	int i = 0, n = 0, c = 0, p = 0;

	// default print to stdout.
	if (fp == NULL)
		fp = stdout;

	while(1) {
		n = size > 0x10 ? 0x10 : size;
		size -= n;

		p += fprintf(fp, "%08X: ", c);
		for(i = 0; i < n; i++) {
			if(i == 8) {
				p += fprintf(fp, " ");
			}
			p += fprintf(fp, "%02X ", *(s + c + i));
		}
		for(i = n; i < 0x10; i++) {
			if(i == 8) {
				p += fprintf(fp, " ");
			}
			p += fprintf(fp, "   ");
		}
		p += fprintf(fp, "   ");
		for(i = 0; i < n; i++) {
			if(*(s + c + i) >= 0x20 && *(s + c + i) <= 0x7E) {
				p += fprintf(fp, "%c", *(s + c + i));
			} else {
				p += fprintf(fp, ".");
			}
		}
		p += fprintf(fp, "\n");
		if(size <= 0) {
			break;
		}
		c += n;
	}
}

// convert string to unsigned int.
// hex: 0x, oct: 0, bin: ...b, dec: normal.
unsigned int atox(char* s)
{
	char *p = s, *e = s;
	unsigned int r = 0;

	while(*e != '\0')
		e++;

	if(*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) {
		// hex: skip first 0x or 0X header.
		p += 2;

		while(p != e) {
			r <<= 4;
			r += ((*p >= '0' && *p <= '9') ? (*p - '0') : ((*p >= 'A' && *p <= 'F') ?
			    *p - 'A' + 0xA : ((*p >= 'a' && *p <= 'f') ? *p - 'a' + 0xA : 0)));
			p++;
		}
	} else if((e - p) >= 2 && *(e - 1) == 'b') {
		// bin: ignore last b.
		e--;

		while(p != e) {
			r <<= 1;
			r += (*p == '0' ? 0 : 1);
			p++;
		}
	} else if(*p == '0') {
		// oct: skip first 0 header.
		p += 1;

		while(p != e) {
			r <<= 3;
			r += ((*p >= '0' && *p <= '7') ? (*p - '0') : 0);
			p++;
		}
	} else {
		// dec: we do not need to deal the number.
		while(p != e) {
			r *= 10;
			r += ((*p >= '0' && *p <= '9') ? (*p - '0') : 0);
			p++;
		}
	}

	return r;
}

int decode_data(unsigned char *out, int max, const char *in)
{
	int used = 0;
	const char *p = in;
	char num[5] = {0};

	while (*p) {
		if (*p == ' ') {
			p++;
			continue;
		}

		if (*p != '0')
			return 0;

		if (used >= max)
			return used;

		memcpy(num, p, 4);
		out[used++] = atox(num);

		p += 4;
	}

	return used;
}

int main(int argc, char *argv[])
{
	unsigned char buf[0x100] = {0};
	int i2c, code, size;

	if (argc != 2 && argc != 5) {
		printf("usage: i2ctest [dev path] [address] [r/w] [length/data]\n");
		printf("\n\nexample:\n");
		printf("\nshow device on i2c-0:\n"
		       "\ti2ctest /dev/i2c-0\n");
		printf("\nread 3 byte from i2c-0, address 0x40:\n"
		       "\ti2ctest /dev/i2c-0 0x40 r 3\n");
		printf("\nwrite 2 byte(0xe2 0x88) to i2c-0, address 0x21:\n"
		       "\ti2ctest /dev/i2c-0 0x21 w '0xe2 0x88'\n\n");
		return 0;
	}

	i2c = open(argv[1], O_RDWR);
	if (i2c < 0) {
		printf("error: can not open device %s\n", argv[1]);
		return -1;
	}

	if (argc == 2) {
		for (code = 0; code < 0x7f; code++) {
			ioctl(i2c, I2C_SLAVE, (unsigned char)code);
			if (errno == EBUSY)
				printf("0x%02x: BUSY\n", code);
			size = write(i2c, buf + code, 1);
			if (size > 0)
				printf("0x%02x: READY\n", code);
		}
		return 0;
	}

	code = ioctl(i2c, I2C_SLAVE, (unsigned char)atox(argv[2]));
	if (code < 0) {
		printf("error: can not set address to %s\n", argv[2]);
		return -1;
	}

	switch (argv[3][0]) {
	case 'r': {
		size = min(sizeof(buf), atox(argv[4]));
		size = read(i2c, buf, size);
		hex_print(buf, size, stdout);
		break; }

	case 'w': {
		size = decode_data(buf, sizeof(buf), argv[4]);
		size = write(i2c, buf, size);
		printf("write: %d byte(s)\n", size);
		break; }

	default: {
		printf("error: unsupport mode %c.\n", argv[3][0]);
		return -1; }
	}

	close(i2c);
	return 0;
}

compile it: mipsel-openwrt-linux-gcc i2ctest.c -o i2ctest

Notify: Shipping Delayed until Feb.10

Recently The well known Corona Virus from Wuhan is spreading very fast…Our China government extended Chinese New Year holiday to Feb.9 in order to slow down the virus spreading. From Jan.20 to Feb.10, we can not ship out any package.

Sorry about the delay, hope the disaster will pass soon…