Samsung TV (anynet+) control with Android Device using HDMI CEC - samsung-smart-tv

I am using command line to control the TV like power on, power off, volume up and volume down from rooted Android Device. i am able to power on and power off using the following command.
Process p;
try {
p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("su" + "\n");
// power on command
os.writeBytes("echo 0x40 0x04" > /sys/class/cec/cmd" + "\n");
os.writeBytes("exit\n");
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
and same as to power off with
os.writeBytes("echo 0x40 0x36" > /sys/class/cec/cmd" + "\n");
but i am unable to control the volume. we can get the codes to send from the following website
(http://www.cec-o-matic.com)
Commands for volume up and down
Volume up : os.writeBytes("echo 0x40 0x44 0x41" > /sys/class/cec/cmd" + "\n");
Volume down : os.writeBytes("echo 0x40 0x44 0x42" > /sys/class/cec/cmd" + "\n");
These commands are not working.
Any reference or documentation regarding this will be much appreciated.

Related

I2C: difference between I2C Tools and python SMBus2

I am trying to understand the i2c protocol and it's implementation through the python SMBus library and I2C Tools for Linux.
Let's look at the following I2C Sequences out of a datasheet: chapter 4.2 for the SFM3003:
I can read out the data, if I first initialise a continuous measurement with $i2cset -y 0x28 0x36 0x08 i
and then run my python script:
from smbus2 import SMBus, i2c_msg
import time
OFFSET_FLOW = -24576 # [-]
SCALEFACTOR_FLOW = 170 # [slm^-1]
OFFSET_TEMP = 0 # [-]
SCALEFACTOR_TEMP = 200 # [°C^-1]
#bus.write_byte_data(0x28, 0x36, 0x08)
msg = i2c_msg.read(0x28, 9)
bus = SMBus(1)
while True:
bus.i2c_rdwr(msg)
data = list(msg)
# JUST SOME CONVERSION FROM HERE ON
flow_bytes = data[0:2]
flow_bytes_converted = bytes(flow_bytes)
flow_raw = int.from_bytes(flow_bytes_converted, byteorder='big', signed=True)
print("flow_raw: ", flow_raw)
flow = (flow_raw-OFFSET_FLOW)/SCALEFACTOR_FLOW
print("flow: ", flow)
temp_bytes = data[3:5]
temp_bytes_converted = bytes(temp_bytes)
temp_raw = int.from_bytes(temp_bytes_converted, byteorder='big', signed=True)
print("temp_raw: ", temp_raw)
temp = (temp_raw-OFFSET_TEMP)/SCALEFACTOR_TEMP
print("temp: ", temp)
time.sleep(0.1)
If I uncomment the line bus.write_byte_data(0x28, 0x36, 0x08) and try to run the python script without initialisation from the command line($i2cset -y 0x28 0x36 0x08 i), I get an Remote I/O Error and see a NACK on my bus after writing 0x08 to the register 0x36.
So how is that command different to what I do with the I2C Linux Tools?

Reading/Writing to LSM6DSOX via SPI from Raspberry Pi

I'm having trouble reading and writing to my Adafruit LSM6DSOX IMU from my Raspberry Pi 4 running Ubuntu 20.04. I need to do it via SPI since I require the bandwidth, but I can only seem to read the WHO_AM_I register successfully. Reading/writing to any other register only returns 0x00. I have verified that I can read data off the IMU from an Arduino via SPI, but if I try to read a register other than 0x0F (the IMU_ID) I get 0x0 as a response. Any insight/ideas what could be causing this would be greatly appreciated!
EDIT: It turns out I can read the following registers:
0x0f : 0x6c
0x13 : 0x1c
0x33 : 0x1c
0x53 : 0x1c
0x73 : 0x1c
These are all random registers however, and the value 0x1C doesn't seem to correspond with anything.
This is my main.py:
import LSM6DSOX
def main():
imu=LSM6DSOX.LSM6DSOX()
imu.initSPI()
whoamI=imu.read_reg(0x0F)
while(whoamI != imu.LSM6DSOX_ID):
imu.ms_sleep(200)
print('searching for IMU')
whoamI=imu.get_id()
print(hex(whoamI))
print('found lsm6dsox IMU')
imu.spi.close()
imu.spi = None
if __name__=="__main__":
main()
This is an excerpt from my LSM6DSOX.py:
def initSPI(self):
# Setup communication SPI
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.mode=0b11 #mode 3, (mode 0 is also fine)
self.spi.max_speed_hz = 500000
return self.spi
def read_reg(self, reg, len=1):
# Set up message
buf = bytearray(len+1)
buf[0] = 0b10000000 | reg # MSB bit must be 1 to indicate a read operation. this is OR'd with the register address you want to read
resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
if len==1:
return resp[1]
else:
return resp[1:] #display recieved data
def write_reg(self, reg, data, len=1):
# Set up message
buf = bytearray(len+1)
buf[0] = 0b00000000 | reg # MSB bit must be 0 to indicate a read operation. this is OR'd with the register address you want to read
buf[1:] =bytes(data)
resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
return resp[1:] #display recieved data

How to Calculate the number of bytes in a sector of the hard disk

I want to know how to calculate the no of bytes in a sector of the hard disk
For Linux you can use below command:
# cat /sys/block/sda/queue/hw_sector_size
512
Where /dev/sda is your hard disk device name.
For Windows you can use IOCTL: IOCTL_DISK_GET_DRIVE_GEOMETRY
https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-ioctl_disk_get_drive_geometry
Sample code for Windows:
{
DISK_GEOMETRY diskGeometry;
GET_LENGTH_INFORMATION lengthInfo;
DWORD bytesReturned;
BOOL ret;
ret = DeviceIoControl(
hDevice, // file handle to the physical device
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&diskGeometry,
sizeof(DISK_GEOMETRY),
&bytesReturned,
NULL);
if (TRUE != ret) {
// Log error and exit
}
bytesPerSector = diskGeometry.BytesPerSector;
}

Lost, trying to connect Intel Edison SPI to ADC using the intel XDC and node

I am using the intel XDK for the first time and I am trying to get a reading from this SPI ADC ADS7951SRGER 12 Bit Analog to Digital Converter 8 Input 1 SAR 24-VQFN (4x4) http://www.ti.com/lit/ds/symlink/ads7950.pdf
its connected like so
SPI_2_RXD -> MISO
SPI_2_TXD -> MOSI
SPI_2_CLK -> SCLK
SPI_2_FS0 -> ADC_CS
I have never used SPI before, I am very lost. I've been searching for 24 hours now and I'm not much closer to understanding what I'm supposed to do here.
here is the current hail mary code I'm trying. all I get back is ffffffff
var x = new m.Spi(0);
x.bitPerWord=12;
x.frequency = 20;
var buf = new Buffer(4);
buf[0] = char('0x0b');
buf[1] = char('0x11');
buf[2] = char('0x11');
buf[3] = char('0x11');
var buf2 = x.write(buf);
console.log("Sent: " + buf.toString('hex') + ". Received: " + buf2.toString('hex'));
Any help is appreciated
In the end, I had to pull the CS (SPI_2_FS0 -> ADC_CS) manually, pulling low before each write/read then high again.

Car OBDII WLAN protocol

I am currently searching for the specification of the WLAN protocoll to get OBDII data. There are some ELM327 similar adapter on the market which enables iPhone to connect to a OBDII interface with WLAN. This because Bluetooth serial port is scrambled because of the accessories interface. Other programs like Torque for android can also use this communication protocol. However I did not find the specs for creating a network client.
Any help is welcomed,
Thanks
Ok, after some more research, I found two sources:
Michael Gile has an open source library for iOS devices, meant for communicating with OBDII WiFi as well as Bluetooth devices.
PLX devices (creators of the KiWi) have a description how to communicate with the KiWi. The description is too large to include here, but it boils down to:
Connect using WiFi (sockets)
Wait until the device returns >
Issue command and await response
Requesting information can be done by sending a command in this format (ASCII characters):
MM PP\r
where MM is the test mode, PP is the PID, and \r is a carriage return (hex: 0x0d). All whitespace characters are ignored by the Kiwi. *Test modes 03 and 04 do not require a PID value.
The 'test modes' that are spoken of, are the ten diagnostic modes as defined in the SAE J1979 standard:
Test mode Description
01 Show current data
02 Show freeze frame data
03 Show diagnostic trouble codes
04 Clear trouble codes and stored values
05 Test results, oxygen sensors
06 Test results, non-continuously monitored
07 Show 'pending' trouble codes
08 Special control mode
09 Request vehicle information
0A Request permanent trouble codes
The PID values are the codes for the sensors in the car. A (non-exhaustive)list of possible PID values is on Wikipedia.
here what i do in C and socket:
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
char *ip = "192.168.0.10";
char str [128];
int i;
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(35000);
if(inet_pton(AF_INET, ip, &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
printf ("reading...\n");
strcpy (str,"AT Z\x0d");
sleep(2);
write (sockfd, str, strlen (str));
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
printf ("received: ");
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
printf ("\r\ntype: ");
fgets (str, sizeof (str), stdin);
i = strlen (str);
if (str [i-1] == 0x0a)
str [i-1] = 0;
strcat (str, "\x0d");
write (sockfd, str, strlen (str));
printf ("\r\n");
}
type 1 or 2 enter, you should see the prompt: ELM327
then after that, type whatever you want, for ex.: AT RV (will show voltage)
then use this pdf for all code:
https://www.obd-2.de/carcode/dl/ELM327DS.pdf
Have a look at ELM327 datasheet
Wifi dongles transparently bind the ELM327 RS232 port to a TCP server.
There's not really a WIFI protocol. You can use the ELM327 protocol via a raw TCP connection instead.
You can sent AT commands and OBD2 commands known as PID's with the telnet command:
telnet 192.168.0.1 35000
On succesful connection you can try to send:
AT Z
and the server should respond with "ELM327" and a version number.