I'm attempting to read data from the VL53L1X-SATEL and the TSL2561 Luminosity Sensor at the same time using I2C on the Raspberry Pi 3 B+. When just the vl53l1x is connected I get the following from i2cdetect -y 1:
pi#BIKE_SENSOR_SYSTEM:~ $ i2cdetect -y 1
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
With just the tsl2561 connected I get:
pi#BIKE_SENSOR_SYSTEM:~ $ i2cdetect -y 1
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
This is as expected.
From what I've read online, in order for them to work together the two devices should be connected in parallel to the corresponding pins on the pi. However, when I do this I get:
pi#BIKE_SENSOR_SYSTEM:~ $ i2cdetect -y 1
00: -- -- 05 -- -- -- -- -- -- -- -- -- --
10: -- -- -- 13 -- -- -- -- -- -- 1a -- -- -- 1e --
20: 20 -- -- -- -- -- 26 -- -- -- -- -- -- -- -- 2f
30: -- -- -- -- -- -- -- -- -- 39 -- -- 3c -- -- --
40: -- -- -- -- -- 45 -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: 60 -- 62 -- -- -- -- -- 68 -- -- -- -- -- -- 6f
70: -- -- -- 73 -- 75 -- --
This changes each time I run i2cdetect -y 1 with only the 39 remaining constant. What do I have to change for i2cdetect to display only the 29 and 39?
Here is how I am connecting the pins:
Related
I have a an AM2320 connected, and its address are as follows i2c_bus=1, i2c_addr=0x5c, i2c_slave=0x0703. I wrote code on the raspberry pi and it all works. I know there are is a device at 0x48, and I am not sure about 0x40, but when I run the command i2cdetect -y 1 I get
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Why don't I see the 0x5c device?
I have a raspberry pi3 and a working board. I'd like one as a i2c master(pi3), and another one is slave(working board).
I'd like to read/write to working board from pi3.
I found it on the Internet.
https://www.spinics.net/lists/linux-i2c/msg30208.html
Following this steps.
I set CONFIG_I2C_SLAVE=y, CONFIG_I2C_SLAVE_EEPROM=y and CONFIG_I2C_CHARDEV=y to kernel of my working board, and set
# echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-1/new_device
[ 233.396818] i2c i2c-5: new_device: Instantiated device slave-24c02 at 0x64
#
I ran the i2cdetect.
I can see the 0x64 device from my working board, but my pi3 can not see it.
(working board)# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
(p3)# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
I just connect SDA1 and SCL1 to working board from pi3.
How to fix it?
my pi3
kerenl: 4.19.97-v8(buildroot-2020.02.8)
Thanks
$ i2cdetect -r -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
$ i2cset -y 1 0x50 0xff 0x21
$ i2cget 1 0x50 0xff
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-1, chip address 0x50, data address
0xff, using read byte data.
Continue? [Y/n] Y
0x20
It’s detected fine, but set, get are not working in 24lc512.
I have a file with millions of lines
And in a script I want to use the following line (which removes unprintable characters) in a loop for a given line range
sed -i $'s/[^[:print:]\t]//g' ~/test.txt
How do I do that ? It needs to run very fast
I've tried
sed -i $"{${line1},${line2}}{s/[^[:print:]\t]//g}" ~/test.txt
which is very slow for range of 1000 lines near the end of the file
I'm not sure of the composition of your test file (how many replacements are needed?), so I can't faithfully reproduce your test, but I'm using my /bin/bash (1168776 bytes in 5714 "lines", with 372073 (31.8%) printable/tab characters).
sed
(Baseline for timing purposes)
$ cp /bin/bash sh; time sed -i $'s/[^[:print:]\t]//g' sh
sed -i $'s/[^[:print:]\t]//g' sh 1.66s user 0.01s system 98% cpu 1.687 total
$ cp /bin/bash sh; time sed -i $'s/[^[:print:]\t]//g' sh
sed -i $'s/[^[:print:]\t]//g' sh 1.74s user 0.01s system 89% cpu 1.945 total
$ cp /bin/bash sh; time sed -i $'s/[^[:print:]\t]//g' sh
sed -i $'s/[^[:print:]\t]//g' sh 1.67s user 0.01s system 97% cpu 1.718 total
Mean average of total times = 1.783s 🚶 (it's important to run multiple times to control for caching. I ran four times and dropped the first to account for caching, then averaged to control for externalities like my web browser)
perl
I translated this to perl to see if that would be faster:
$ cp /bin/bash sh; time perl -i -pe $'s/[^[:print:]\t]//g' sh
perl -i -pe $'s/[^[:print:]\t]//g' sh 0.18s user 0.01s system 92% cpu 0.208 total
$ cp /bin/bash sh; time perl -i -pe $'s/[^[:print:]\t]//g' sh
perl -i -pe $'s/[^[:print:]\t]//g' sh 0.18s user 0.01s system 68% cpu 0.271 total
$ cp /bin/bash sh; time perl -i -pe $'s/[^[:print:]\t]//g' sh
perl -i -pe $'s/[^[:print:]\t]//g' sh 0.21s user 0.00s system 81% cpu 0.258 total
Mean average of total times = 0.246s 🏃
However, I noticed some differences. GNU sed is struggling, perhaps due to either a different definition of the [:print:] class or (more likely) different handling of control characters:
$ sed $'s/[^[:print:]\t]//g' /bin/bash |head -c64 |hd
00000000 45 4c 46 3e 30 f6 40 48 ce 40 38 40 40 40 40 68 |ELF>0.#H.#8####h|
00000010 68 a8 a8 a8 98 cd 98 cd d0 d0 d0 8d d7 0a 8d d7 |h...............|
00000020 0a b0 b0 b0 30 57 30 57 f0 f0 23 f0 23 b9 a8 55 |....0W0W..#.#..U|
00000030 f0 3c f0 4c f0 4c c4 c4 c4 44 44 50 e5 74 64 30 |.<.L.L...DDP.td0|
00000040
$ perl -pe $'s/[^[:print:]\t]//g' /bin/bash |head -c64 |hd
00000000 45 4c 46 3e 30 40 48 40 38 40 40 40 40 68 68 30 |ELF>0#H#8####hh0|
00000010 57 30 57 23 23 55 3c 4c 4c 44 44 50 74 64 30 49 |W0W##U<LLDDPtd0I|
00000020 30 49 30 49 44 44 51 74 64 52 74 64 23 23 2c 2c |0I0IDDQtdRtd##,,|
00000030 2f 6c 69 62 36 34 2f 6c 64 2d 6c 69 6e 75 78 2d |/lib64/ld-linux-|
00000040
See all those dots in the GNU sed output? Those are failures to replace content. I also observe these in Busybox sed. BSD sed (which is used by Mac OS X) does not appear to have this limitation, but note this for portability purposes as needed.
tr
$ cp /bin/bash sh; time tr -cd $'[ -~\t\n]' < sh > sh-tr && mv sh-tr sh
tr -cd $'[[:print:]\t]' < sh > sh-tr 0.00s user 0.01s system 62% cpu 0.012 total
$ cp /bin/bash sh; time tr -cd $'[ -~\t\n]' < sh > sh-tr && mv sh-tr sh
tr -cd $'[[:print:]\t]' < sh > sh-tr 0.00s user 0.01s system 81% cpu 0.009 total
$ cp /bin/bash sh; time tr -cd $'[ -~\t\n]' < sh > sh-tr && mv sh-tr sh
tr -cd $'[[:print:]\t]' < sh > sh-tr 0.00s user 0.01s system 82% cpu 0.012 total
Mean average of total times = 0.011s ⚡️
I've tested this with GNU tr and Busybox tr (they have equal performance). We're using tr to delete (-d) rather than translate, and we're acting on the complement (-c) of the given class (tr does not use regex, so we can't invert the character class with a caret the way we can in sed).
Busybox tr does not support $'[[:print:]\t]' so I have converted it to a range from space to tilde (all printable lower-ASCII except tab and newline) and I added not just tab but also newline since tr needs to explicitly preserve that character (sed did not). If the lines don't match properly, consider adding \r to the replacement set.
strings is also good here, but it does not preserve lines (it replaces each contiguous string of non-printable characters with a newline)
I want to copy a .csv file into a postgresql table, where the file name is a variable. It fails with a "no such file or directory" error if \COPY and a user other than postgres is used. However, the copy succeeds if COPY and the postgres user is used.
The failing script:
martin#opensuse1:~> ./test1.sh
Null display is "¤".
'/home/martin/20180423.csv'
psql:load.sql:2: :load_csv: No such file or directory
martin#opensuse1:~> cat test1.sh
load_csv=/home/martin/20180423.csv
psql -d test1 -e -f load.sql --variable=load_csv="'$load_csv'"
martin#opensuse1:~> cat load.sql
\echo :load_csv
\copy test_table (col1, col2, col3) FROM :load_csv delimiter ';' encoding 'LATIN1' NULL '';
martin#opensuse1:~>
The working script:
martin#opensuse1:~> ./test1.sh
Null display is "¤".
'/home/martin/20180423.csv'
copy test_table (col1, col2, col3) FROM '/home/martin/20180423.csv' delimiter ';' encoding 'LATIN1' NULL '';
COPY 3
martin#opensuse1:~> cat test1.sh
load_csv=/home/martin/20180423.csv
psql -w postgres -d test1 -e -f load.sql --variable=load_csv="'$load_csv'"
martin#opensuse1:~> cat load.sql
\echo :load_csv
copy test_table (col1, col2, col3) FROM :load_csv delimiter ';' encoding 'LATIN1' NULL '';
martin#opensuse1:~>
What can I do to make this script run without having to use the postgres user?
Martin
It seems that the psql variables are not substituted in the \copy command.
A solution is to write the \copy command to a file and execute that file.
The part from my script (load the table par from the tsv-file with the
name stored in :input_file) is:
-- Tuples only:
\t on
-- Output file:
\o load_cmd.sql
select concat('\copy par from ''', :'input_file', '.tsv'';');
-- Standard output again:
\o
-- Normal decoration of tables:
\t off
-- Now execute the file with the \copy command:
\i load_cmd.sql