![]() |
Forum Index : Microcontroller and PC projects : How to read a 12 bit value in MMBasic (touch controller NS2009)
Author | Message | ||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
Need help How to convert this C function to a MMBasic version? //read 12bit data unsigned int ns2009_read(uint8_t cmd) { uint8_t buf[2]; ns2009_recv(&cmd, 1, buf, 2); return (buf[0] << 4) | (buf[1] >> 4); } ![]() ![]() / Peter63 |
||||
Andy-g0poy Regular Member ![]() Joined: 07/03/2023 Location: United KingdomPosts: 73 |
The c function is simple. take the value in buf[0] and shift it left by 4 bits (shifts everything along leaving the lower 4 bits clear) Take the value in buf[1] and shift it right by 4 bits (moves the 4 lsb bits into the upper 4 bits) biwise OR the two bufs and return the result. giving you the 12 bit result. You can do the same thing with the MMBASIC Shift operators, and the OR operator. Andy |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4006 |
I think the 2nd explanation should be Take the value in buf[1] and shift it right by 4 bits (moves the 4 upper bits into the lower 4 bits) (And because uint8_t is unsigned 8-bit type the upper bits shifted in will be zeros.) John |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
Can anyone show this in MMBasic code ![]() Function ns2009_read(cmd) As integer ??? End Function /Peter63 |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7585 |
You could probably just read the I2C register in MMBasic using the I2C commands. Open the connection as I2C master and use I2C Read to get the number of bytes that you want. In the above example you can simply read 2 bytes from the chip. You can read them into two successive elements of an array. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
My own function looks like this, but I don't know if I'm doing the right thing Function nsread(cmd) AS integer Local s As string Local a As string Local b As string I2C write &H48,0,1,cmd I2C read &H48,0,2,s a=Mid$(s,1,1) b=Mid$(s,2,1) nsread = (Asc(a)<<4) Or (Asc(b)>>4) End Function ' I call on the function in the main program like this x=nsread(&HC0) ' read X-pos y=nsread(&HD0) ' read Y-pos ![]() /Peter63 |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1193 |
I just asked Copilot and it came back with: REM Read 12-bit data FUNCTION ns2009_read(cmd AS INTEGER) AS INTEGER DIM buf(1) AS INTEGER CALL ns2009_recv(cmd, 1, buf(), 2) ns2009_read = (buf(0) * 16) + (buf(1) / 16) END FUNCTION |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
Here is the C program I'm trying to translate into mmBasic code I want to be able to read x and y position from NS2009 in MMBasic file: NS2009.h --------------- #include <Wire.h> //NS2009 #define NS2009_ADDR 0x48 //10010000 #define NS2009_LOW_POWER_READ_X 0xc0 #define NS2009_LOW_POWER_READ_Y 0xd0 #define NS2009_LOW_POWER_READ_Z1 0xe0 #define SCREEN_X_PIXEL 320 #define SCREEN_Y_PIXEL 480 void ns2009_recv(const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf, size_t receive_buf_len); unsigned ns2009_read(uint8_t cmd, int *val); int ns2009_pos(int pos[2]); int ns2009_get_press(); file: NS2009.cpp ------------------ #include "NS2009.h" //I2C receive void ns2009_recv(const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf, size_t receive_buf_len) { Wire.beginTransmission(NS2009_ADDR); Wire.write(send_buf, send_buf_len); Wire.endTransmission(); Wire.requestFrom(NS2009_ADDR, receive_buf_len); while (Wire.available()) { *receive_buf++ = Wire.read(); } } //read 12bit data unsigned int ns2009_read(uint8_t cmd) { uint8_t buf[2]; ns2009_recv(&cmd, 1, buf, 2); return (buf[0] << 4) | (buf[1] >> 4); } //Press maybe not correct int ns2009_get_press() { return ns2009_read(NS2009_LOW_POWER_READ_Z1); } int ns2009_pos(int pos[2]) { int press = ns2009_read(NS2009_LOW_POWER_READ_Z1); int x, y = 0; x = ns2009_read(NS2009_LOW_POWER_READ_X); y = ns2009_read(NS2009_LOW_POWER_READ_Y); pos[0] = x * SCREEN_X_PIXEL / 4096; //4096 = 2 ^ 12 pos[1] = y * SCREEN_Y_PIXEL / 4096; //pos[0] = x; //pos[1] = y; return press; } /Peter63 |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7585 |
Why convert the C code at all? Just off the top of my head. I can't test this and it probably won't work for one reason or another. In particular you will probably need a delay after each read to allow it to complete before you can manipulate anything. This example is using 100kHz and a 100ms timeout with no error trapping. Variables on the Pico are 64 bit, so you can read an 8-bit value and shift it up by eight bits then add another 8-bit value. The lowest four bits of the second value are &b0000 so you can then shift the entire value down by four bits. You are left with a 12 bit value. I'm definitely not saying this will work, I'm no programmer I'm a hardware guy, but it seems more logical to investigate what MMBasic can do alone before attempting to recode C. get.touch a, b, c print "x value is"a print "y value is"y print "z value is"z sub get.touch(x,y,z) dim local n(2) i2c open 100,100 i2c read &hC0, 0, n() x = (n(0)<<8+n(1))>>4 i2c read &hD0, 0, n() y = (n(0)<<8+n(1))>>4 i2c read &hE0, 0, n() z = (n(0)<<8+n(1))>>4 i2c close end sub Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
Thanks Mick I understand, I'm going to test further with MMBasic code. Thank you for your post and code. Will return when I have made some progress. /Peter63 |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
Assuming option base 0 and I2C is opened at the start of the program and closed at the end ' FUNCTION nsread(cmd) AS INTEGER LOCAL rec%(2) I2C WRITE &H48,0,1,cmd I2C READ &H48,0,2,rec%() nsread = (rec%(0)<<4) + (rec%(1)>>4) END FUNCTION Jim VK7JH MMedit |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
Reading from NS2009 now works / thanks Jim ![]() ![]() /Peter63 |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7585 |
That's a very neat solution, Jim. Mine was way too clumsy (and wrong as expected, of course). lol Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
' ' Test program to read from NS2009 ' 4-Wire Touch Screen Controller with I2C Interface ' ' using WebMite MMBasic RP2350A Edition V6.00.01RC9 ' CLS Font 3 Text 0,0,"Paint" SetPin GP0,GP1,I2C ' set I/O pins for I2C screen_x_pixel = 320 ' 320 screen_y_pixel = 240 ' 240 Dim x As integer Dim y As integer Dim z As integer I2C open 100,5000 Do z=nsread(HE0) ' read press-value If z > 150 Then x=nsread(&HC0) ' read x-pos y=nsread(&HD0) ' read y-pos ' landscape mode screen_pixel flipped xx = Int(x * screen_y_pixel / 4096) yy = Int(y * screen_y_pixel / 4096) Circle yy,xx,2,1 End If Loop Until Inkey$<>"" I2C close End ' --- read NS2009 Function nsread(cmd) As integer Local rec%(2) I2C write &H48,0,1,cmd ' &H48 = address NS2009 I2C read &H48,0,2,rec%() nsread = (rec%(0)<<4) + (rec%(1)>>4) End Function -------------------------------- /Peter63 |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1193 |
@Peter63 FYI: Always easier to read code when bracketed as such: ![]() ' ' Test program to read from NS2009 ' 4-Wire Touch Screen Controller with I2C Interface ' ' using WebMite MMBasic RP2350A Edition V6.00.01RC9 ' CLS Font 3 Text 0,0,"Paint" SetPin GP0,GP1,I2C ' set I/O pins for I2C screen_x_pixel = 320 ' 320 screen_y_pixel = 240 ' 240 Dim x As integer Dim y As integer Dim z As integer I2C open 100,5000 Do z=nsread(HE0) ' read press-value If z > 150 Then x=nsread(&HC0) ' read x-pos y=nsread(&HD0) ' read y-pos ' landscape mode screen_pixel flipped xx = Int(x * screen_y_pixel / 4096) yy = Int(y * screen_y_pixel / 4096) Circle yy,xx,2,1 End If Loop Until Inkey$<>"" I2C close End ' --- read NS2009 Function nsread(cmd) As integer Local rec%(2) I2C write &H48,0,1,cmd ' &H48 = address NS2009 I2C read &H48,0,2,rec%() nsread = (rec%(0)<<4) + (rec%(1)>>4) End Function |
||||
Peter63 Regular Member ![]() Joined: 28/07/2017 Location: SwedenPosts: 47 |
Thanks for the info, much easier to read code then /Peter63 |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7585 |
Bracketed code also retains indents properly. sub Icount for i = 0 to 55 'a comment print i 'a nother comment next end sub sub Icount for i = 0 to 55 'a comment print i 'a nother comment next end sub Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |