RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - Mark Power - 01-15-2022 03:20 PM
Ok, I think I have answered my own question on pins:
FT260 spec sheet says that DIO5 = SCL and DIO6 = SDA
UMFT260EV1A spec sheet says that IO0 = DIO5 and IO1 = DIO6
Therefore on the UMFT260EV1A:
IO0 = SCL
IO1 = SDA
Any chance you could supply the source code for reading the data from the BME680 that is shown in the jpgs?
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - gehakte_bits - 01-15-2022 03:36 PM
Those pins are correct, but they are in reference to ground, so connect at least ground too.
I cannot share the source code, but here is a good guide:
https://github.com/BoschSensortec/BME68x-Sensor-API/releases/tag/v4.4.6
using the floating point algos, cause that is what the Prime does very well.
(Although I see they upped it to v4.4.7)
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - StephenG1CMZ - 08-11-2022 08:35 PM
As an alternative to generating an actual Beep (tones or audio) :
How about some option to send print strings to the connectivity kit, which could then connect to some external voice synthesis system or generate tones, whilst the calculator itself remains mute for exams?
That could also be useful for accessibility.
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - muteki - 09-15-2022 03:54 PM
I thought the holy grail (on G1) would be soldering a piezo to the unused piezo pad and use an ACE exploit in firmware to call
Jokes aside, one can also use a Raspberry Pi Pico connected via OTG. Not only it's only $4, being available everywhere, you also got much more I/O options (SPI or even efficient bitbanging for weird sensors like DHT11). The sky (and also the 64KB/s hard limit of transfer rate unfortunately) is the limit.
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - CWILT - 10-30-2022 04:29 AM
I have a cable coming next week and will try to use a bus pirate device with the G2. Will update when I can.
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - matalog - 03-11-2023 10:37 PM
Does anyone have any videos of working with this particular project, of attempts, fails or successes?
I would like to get in/out from my Prime, but I am not exactly sure which interface board I would be best buying, at the minute. Or which sides of which USB devices I would have to use to connect to PC or other devices. The suggested interface had a USB in and 3 PIN's out or vice versa.
It would be great to see any progress that Anyone has made on it, even if it was not progress, something might be learned by those that haven't dared to try yet.
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - matalog - 04-27-2023 03:13 PM
Does the cable at the end of the HP Prime, have to be the OTG type? Not just a normal USB B cable? I plan to try it out with a HID USB Host Controller and just want to know if the OTG connection if required in the Micro B plug?
RE: The holy grail of the BEEP(1400, 0.08) command: USB-HID - Mark Power - 05-01-2023 08:59 PM
Quote: It would be great to see any progress that Anyone has made on it, even if it was not progress, something might be learned by those that haven't dared to try yet.
I have been playing with the FT260 and BME680 but have not had much time to devote to reproducing the OP's solution. So far:
I have found a bug in the originally posted code for getregs(). It doesn't handle retrieving more than 52 registers (bytes) at a time. Add line 262 reg:=reg+bsize; so that the block of code looks like this:
Code:
// set register #D0 'i2ca' #06 #01 #'reg'
ft260_i2cSend(i2ca,{reg});
reg:=reg+bsize; // update the register to be read if reading more than max block size registers
// read request p bytes #C2 'i2ca' #06 #low #high
sts:=CONCAT(sts,ft260_i2cReadReq(i2ca, p));
I started implementing the BME680 code from the Bosch pseudo code and C code. Unfortunately, firstly the results for temp and pressure seem inaccurate, so I think I have missed something but I'm not sure what exactly. Secondly, I tried implementing the Bosch integer algorithms to check that my implementation of the floating point routines was correct. The two versions of the temperature code give the same result. When it came to implementing the integer version of the pressure code, the program currently crashes as my conversion from C to PPL was too simplistic - I need to alter the integer code to use 2's complement ints so that negative numbers are handled correctly. These are my additions to the OP's supplied code if anyone else wants to play:
Code:
// MP's additions to connect Bosch BME680 temperature, pressure,
// humidity and air quality (gas resistance) sensor to FT260
// Make a list follow C convention of first element being zero
List0(lst)
BEGIN
RETURN(CONCAT(tail(lst), head(lst)));
END;
// Reorder a list modified by List0() so that index 1 is the first element
// as per normal Prime convention
List1(lst)
BEGIN
RETURN(CONCAT(lst(0), SUB(lst,1,SIZE(lst)-1)));
END;
// Check if ft260 and bme680 are connected and try to take sensor readings
EXPORT check_ft260_bme680()
BEGIN
LOCAL sts, temp_comp;
LOCAL bme260_raw:={};
LOCAL bme260_mm:={};
LOCAL temp_res:={};
LOCAL t_fine:=0;
PRINT;
IF EQ(UClose(),{{1027,24624}}) THEN
IF EQ(ft260_open(),{64,64}) THEN
IF EQ(getregs(#76h, #D0h, 1),{1,{97}}) THEN
PRINT("Connected");
// Perform one forced measurement of temp and pressure
// osrs_t = 010b, osrs_p = 010b, mode = 01b = 49h
sts:=setreg(#76h,{#74h,#49h});
PRINT(sts);
// Read the entire contents of the 256 registers in the BME680
bme260_raw:=getregs(#76h,#0,256);
// Build list of all results with index zero being first register
bme260_mm:=List0(bme260_raw(2));
// Calculate temperature according to Bosch document
temp_res:=calc_temp_float(bme260_mm);
t_fine:=temp_res(2);
calc_press_float(bme260_mm, t_fine);
// Check temp calculation by also using the int code
temp_res:=calc_temp_integer(bme260_mm);
t_fine:=temp_res(2);
L3:=calc_press_integer(bme260_mm, t_fine);
UClose();
RETURN(L3);
ELSE
RETURN("BME680 not connected");
END;
ELSE
RETURN("FTE260 report error");
END;
ELSE
RETURN("FT260 not connected");
END;
END;
EXPORT calc_temp_float(data)
BEGIN
LOCAL temp_adc, t_fine, temp_comp, par_t1, par_t2, par_t3, var1, var2;
temp_adc:=data(#22h)*256*16+data(#23h)*16+IP(data(#24h)/16);
par_t1:=data(#EAh)*256+data(#E9h);
par_t2:=data(#8Bh)*256+data(#8Ah);
par_t3:=data(#8Ch);
var1:=((temp_adc/16384)-(par_t1/1024))*par_t2;
var2:=(((temp_adc/131072)-(par_t1/8192))*
((temp_adc/131072)-(par_t1/8192)))*
(par_t3*16);
t_fine:=var1+var2;
temp_comp:=t_fine/5120;
PRINT("temp_comp "+STRING(temp_comp));
PRINT("t_fine "+STRING(t_fine));
RETURN({temp_comp, t_fine});
END;
EXPORT calc_press_float(data, t_fine)
BEGIN
LOCAL press_adc, press_comp;
LOCAL par_p1, par_p2, par_p3, par_p4, par_p5;
LOCAL par_p6, par_p7, par_p8, par_p9, par_p10;
LOCAL var1, var2, var3;
press_adc:=data(#1Fh)*256*16+data(#20h)*16+IP(data(#21h)/16);
par_p1:=data(#8Fh)*256+data(#8Eh);
par_p2:=data(#91h)*256+data(#90h);
par_p3:=data(#92h);
par_p4:=data(#95h)*256+data(#94h);
par_p5:=data(#97h)*256+data(#96h);
par_p6:=data(#99h);
par_p7:=data(#98h);
par_p8:=data(#9Dh)*256+data(#9Ch);
par_p9:=data(#9Fh)*256+data(#9Eh);
par_p10:=data(#A0h);
var1:=(t_fine/2)-64000;
var2:=var1*var1*(par_p6/131072);
var2:=var2+(var1*par_p5*2);
var2:=(var2/4)+(par_p4*65536);
var1:=(((par_p3*var1*var1)/16384)+(par_p2*var1))/524288;
var1:=(1+(var1/32768))*par_p1;
press_comp:=1048576-press_adc;
// Avoid exception caused by division by zero
IF IP(var1) THEN
press_comp:=((press_comp-(var2/4096))*6250)/var1;
var1:=(par_p9*press_comp*press_comp)/2147483648;
var2:=press_comp*(par_p8/32768);
var3:=(press_comp/256)*(press_comp/256)*(press_comp/256)*(par_p10/131072);
press_comp:=press_comp+(var1+var2+var3+(par_p7*128))/16;
ELSE
press_comp:=0;
END;
PRINT("press_comp "+STRING(press_comp));
RETURN(press_comp);
END;
EXPORT calc_temp_integer(data)
BEGIN
LOCAL temp_adc, t_fine, temp_comp;
LOCAL par_t1, par_t2, par_t3;
LOCAL var1, var2, var3;
temp_adc:=BITSL(data(#22h),12)+BITSL(data(#23h),4)+BITSR(data(#24h),4);
par_t1:=BITSL(data(#EAh),8)+data(#E9h);
par_t2:=BITSL(data(#8Bh),8)+data(#8Ah);
par_t3:=data(#8Ch);
var1:=BITSR(temp_adc,3)-BITSL(par_t1,1);
var2:=BITSR(var1*par_t2,11);
var3:=BITSR(BITSR(var1,1)*BITSR(var1,1),12);
var3:=BITSR(var3*BITSL(par_t3,4),14);
t_fine:=var2+var3;
temp_comp:=BITSR((t_fine*5)+128,8);
PRINT("temp_comp "+STRING(temp_comp/100));
PRINT("t_fine "+STRING(t_fine));
RETURN({temp_comp/100, t_fine});
END;
EXPORT calc_press_integer(data, t_fine)
BEGIN
LOCAL press_adc, press_comp;
LOCAL par_p1, par_p2, par_p3, par_p4, par_p5;
LOCAL par_p6, par_p7, par_p8, par_p9, par_p10;
LOCAL var1, var2, var3;
press_adc:=BITSL(data(#1Fh),12)+BITSL(data(#20h),4)+BITSR(data(#21h),4);
par_p1:=BITSL(data(#8Fh),8)+data(#8Eh);
par_p2:=BITSL(data(#91h),8)+data(#90h);
par_p3:=data(#92h);
par_p4:=BITSL(data(#95h),8)+data(#94h);
par_p5:=BITSL(data(#97h),8)+data(#96h);
par_p6:=data(#99h);
par_p7:=data(#98h);
par_p8:=BITSL(data(#9Dh),8)+data(#9Ch);
par_p9:=BITSL(data(#9Fh),8)+data(#9Eh);
par_p10:=data(#A0h);
// This returns a negative value and the later code bombs
// Need to change all int code over to correctly using signed 2's complement ints
var1:=BITSR(IP(t_fine),1)-#64000d;
DEBUG;
var2:=BITSR(BITSR(BITSR(var1,2)*BITSR(var1,2),11)*par_p6,2);
var2:=var2+BITSL(var1*par_p5,1);
var2:=BITSR(var2,2)+BITSL(par_p4,16);
var1:=BITSR(BITSR(BITSR(var1,2)*BITSR(var1,2),13)*BITSL(par_p3,5),3)+BITSR(par_p2*var1,1);
var1:=BITSR(var1,18);
var1:=BITSR((32768+var1)*par_p1,15);
press_comp:=1048576-press_adc;
press_comp:=(press_comp-BITSR(var2,12))*3125;
IF press_compā„BITSL(1,30) THEN
press_comp:=BITSL(press_comp/var1,1);
ELSE
press_comp:=BITSL(press_comp,1)/var1;
END;
var1:=BITSR(par_p9*BITSR(BITSR(press_comp,3)*BITSR(press_comp,3),13),12);
var2:=BITSR(BITSR(press_comp,2)*par_p8,13);
var3:=BITSR(BITSR(press_comp,8)*BITSR(press_comp,8)*BITSR(press_comp,8)*par_p10,17);
press_comp:=press_comp+BITSR(var1+var2+var3+BITSL(par_p7,7),4);
PRINT("press_comp "+STRING(press_comp));
RETURN(press_comp);
END;
|