- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试转换一个解析 Linux 库 rtl_fm 输出的 C 模块。它用于通过 DVB-T 加密狗从 Efergy 仪表捕获能源使用情况
C 模块工作正常,但我希望它用 python 编写以与我拥有的其他 python 模块交互
我把常量放在了constant.py
我完全被困在转换行:cursamp = (int16_t) (fgetc(stdin) | fgetc(stdin)<<8); 我已经尝试转换成很多不同的方法。每次尝试都以错误结束!
好像是两类问题:1.输入结果的类型转换 2.如何将fgetc()转成python。
我也无法将 while(!feof(stdin)) 转换为 python
有人可以帮忙吗?
C 代码如下:
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <math.h>
#include <stdlib.h> // For exit function
#define VOLTAGE 240 /* Refernce Voltage */
#define CENTERSAMP 100 /* Number of samples needed to compute for the wave center */
#define PREAMBLE_COUNT 40 /* Number of high(1) samples for a valid preamble */
#define MINLOWBIT 3 /* Number of high(1) samples for a logic 0 */
#define MINHIGHBIT 8 /* Number of high(1) samples for a logic 1 */
#define E2BYTECOUNT 8 /* Efergy E2 Message Byte Count */
#define FRAMEBITCOUNT 64 /* Number of bits for the entire frame (not including preamble) */
#define LOGTYPE 1 // Allows changing line-endings - 0 is for Unix /n, 1 for Windows /r/n
#define SAMPLES_TO_FLUSH 10 // Number of samples taken before writing to file.
// Setting this too low will cause excessive wear to flash due to updates to
// filesystem! You have been warned! Set to 10 samples for 6 seconds = every min.
int loggingok; // Global var indicating logging on or off
int samplecount; // Global var counter for samples taken since last flush
FILE *fp; // Global var file handle
int calculate_watts(char bytes[])
{
char tbyte;
double current_adc;
double result;
int i;
time_t ltime;
struct tm *curtime;
char buffer[80];
/* add all captured bytes and mask lower 8 bits */
tbyte = 0;
for(i=0;i<7;i++)
tbyte += bytes[i];
tbyte &= 0xff;
/* if checksum matches get watt data */
if (tbyte == bytes[7])
{
time( <ime );
curtime = localtime( <ime );
strftime(buffer,80,"%x,%X", curtime);
current_adc = (bytes[4] * 256) + bytes[5];
result = (VOLTAGE * current_adc) / ((double) 32768 / (double) pow(2,bytes[6]));
printf("%s,%f\n",buffer,result);
if(loggingok) {
if(LOGTYPE) {
fprintf(fp,"%s,%f\r\n",buffer,result);
} else {
fprintf(fp,"%s,%f\n",buffer,result);
}
samplecount++;
if(samplecount==SAMPLES_TO_FLUSH) {
samplecount=0;
fflush(fp);
}
}
fflush(stdout);
return 1;
}
//printf("Checksum Error \n");
return 0;
}
void main (int argc, char**argv)
{
char bytearray[9];
char bytedata;
int prvsamp;
int hctr;
int cursamp;
int bitpos;
int bytecount;
int i;
int preamble;
int frame;
int dcenter;
int dbit;
long center;
if(argc==2) {
fp = fopen(argv[1], "a"); // Log file opened in append mode to avoid destroying data
samplecount=0; // Reset sample counter
loggingok=1;
if (fp == NULL) {
perror("Failed to open log file!"); // Exit if file open fails
exit(EXIT_FAILURE);
}
} else {
loggingok=0;
}
printf("Efergy E2 Classic decode \n\n");
/* initialize variables */
cursamp = 0;
prvsamp = 0;
bytedata = 0;
bytecount = 0;
hctr = 0;
bitpos = 0;
dbit = 0;
preamble = 0;
frame = 0;
dcenter = CENTERSAMP;
center = 0;
while( !feof(stdin) )
{
cursamp = (int16_t) (fgetc(stdin) | fgetc(stdin)<<8);
/* initially capture CENTERSAMP samples for wave center computation */
if (dcenter > 0)
{
dcenter--;
center = center + cursamp; /* Accumulate FSK wave data */
if (dcenter == 0)
{
/* compute for wave center and re-initialize frame variables */
center = (long) (center/CENTERSAMP);
hctr = 0;
bytedata = 0;
bytecount = 0;
bitpos = 0;
dbit = 0;
preamble = 0;
frame = 0;
}
}
else
{
if ((cursamp > center) && (prvsamp < center)) /* Detect for positive edge of frame data */
hctr = 0;
else
if ((cursamp > center) && (prvsamp > center)) /* count samples at high logic */
{
hctr++;
if (hctr > PREAMBLE_COUNT)
preamble = 1;
}
else
if (( cursamp < center) && (prvsamp > center))
{
/* at negative edge */
if ((hctr > MINLOWBIT) && (frame == 1))
{
dbit++;
bitpos++;
bytedata = bytedata << 1;
if (hctr > MINHIGHBIT)
bytedata = bytedata | 0x1;
if (bitpos > 7)
{
bytearray[bytecount] = bytedata;
bytedata = 0;
bitpos = 0;
bytecount++;
if (bytecount == E2BYTECOUNT)
{
/* at this point check for checksum and calculate watt data */
/* if there is a checksum mismatch compute for a new wave center */
if (calculate_watts(bytearray) == 0)
dcenter = CENTERSAMP; /* make dcenter non-zero to trigger center resampling */
}
}
if (dbit > FRAMEBITCOUNT)
{
/* reset frame variables */
bitpos = 0;
bytecount = 0;
dbit = 0;
frame = 0;
preamble = 0;
bytedata = 0;
}
}
hctr = 0;
}
else
hctr = 0;
if ((hctr == 0) && (preamble == 1))
{
/* end of preamble, start of frame data */
preamble = 0;
frame = 1;
}
} /* dcenter */
prvsamp = cursamp;
} /* while */
if(loggingok) {
fclose(fp); // If rtl-fm gives EOF and program terminates, close file gracefully.
}
}
和 Python 转换(略微简化,没有文件记录):
from datetime import date
from datetime import time
from datetime import datetime
import cmath
import constant
import sys
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
def calculate_watts(*args):
logger.info('Start Calculation')
now = datetime.now()
tbyte = 0
for i in range(0,7):
tbyte += bytes[i]
tbyte = tbyte & 0xff
if (tbyte == bytes[7]):
current_adc = (bytes[4] * 256) + bytes[5]
result = (constant.VOLTAGE * current_adc) / (32768 / pow(2,bytes[6]))
print "%s,%f\n" % (now,result)
exit(0)
else:
print "Checksum Error \n"
exit(1)
def main(*argv):
logger.info('Starting Main')
print "Efergy E2 Python decode \n\n"
cursamp = 0
prvsamp = 0
bytedata = 0
bytecount = 0
hctr = 0
bitpos = 0
dbit = 0
preamble = 0
frame = 0
dcenter = constant.CENTERSAMP
center = 0
while (1):
cursamp = (int)((int)(_Getch()) | (int)(_Getch())<<8)
logger.debug('cursamp: %f',cursamp)
if (dcenter > 0):
dcenter -= 1
center = center + cursamp #/* Accumulate FSK wave data */
if (dcenter == 0):
center = (center/constant.CENTERSAMP)
hctr = 0
bytedata = 0
bytecount = 0
bitpos = 0
dbit = 0
preamble = 0
frame = 0
else:
if ((cursamp > center) and (prvsamp < center)): #/* Detect for positive edge of frame data */
hctr = 0
else:
if ((cursamp > center) and (prvsamp > center)): #/* count samples at high logic */
hctr += 1
if (hctr > constant.PREAMBLE_COUNT):
preamble = 1
else:
if (( cursamp < center) and (prvsamp > center)):
#/* at negative edge */
if ((hctr > constant.MINLOWBIT) and (frame == 1)):
dbit += 1
bitpos += 1
bytedata = bytedata << 1
if (hctr > constant.MINHIGHBIT):
bytedata = bytedata | 0x1
if (bitpos > 7):
bytearray[bytecount] = bytedata
bytedata = 0
bitpos = 0
bytecount += 1
if (bytecount == constant.E2BYTECOUNT):
# /* at this point check for checksum and calculate watt data */
# /* if there is a checksum mismatch compute for a new wave center */
if (calculate_watts(bytearray) == 0):
dcenter = constant.CENTERSAMP #/* make dcenter non-zero to trigger center resampling */
if (dbit > constant.FRAMEBITCOUNT):
#/* reset frame variables */
bitpos = 0
bytecount = 0
dbit = 0
frame = 0
preamble = 0
bytedata = 0
hctr = 0
else:
hctr = 0
if ((hctr == 0) and (preamble == 1)):
#/* end of preamble, start of frame data */
preamble = 0
frame = 1
#/* dcenter */
prvsamp = cursamp
if __name__ == "__main__":
main()
最佳答案
C 的 fgetc(stdin)
转换为 Python 2 的 ord(sys.stdin.read(1)[0])
-- 从 stdin
的下一个字节返回一个数值. (在 Python 3 中,您必须以二进制形式重新打开 sys.stdin
才能实现这一点,否则 .read(1)
将获得 Unicode 字符,而不是字节)。
|
和 <<
运算符在 Python 中的工作方式与在 C 中的工作方式相同,因此,这没有问题。
在 EOF,sys.stdin.read(1)
返回一个空列表(因此 [0]
会失败,但您可以通过“分解”上述表达式来检查)。例如:
ateof = False
def getabyte():
data = sys.stdin.read(1)
if data: return False, ord(data)
else: return True, 0
def getanint():
global ateof
ateof, byte1 = getabyte()
if not ateof:
ateof, byte2 = getabyte()
if ateof: return True, 0
else: return False, byte1 | (byte2<<8)
关于字节顺序(字节顺序)和字符符号(C 和 Python 的常见问题)的挑剔问题。
关于python - 将 C 转换为 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27826610/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!