Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 01:25 24 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

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: Sweden
Posts: 47
Posted: 09:50am 15 Feb 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 73
Posted: 10:23am 15 Feb 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 4006
Posted: 11:18am 15 Feb 2025
Copy link to clipboard 
Print this post

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: Sweden
Posts: 47
Posted: 12:15pm 15 Feb 2025
Copy link to clipboard 
Print this post

Can anyone show this in MMBasic code  


Function ns2009_read(cmd) As integer

???

End Function

/Peter63
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7585
Posted: 12:34pm 15 Feb 2025
Copy link to clipboard 
Print this post

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: Sweden
Posts: 47
Posted: 01:19pm 15 Feb 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1193
Posted: 02:09pm 15 Feb 2025
Copy link to clipboard 
Print this post

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: Sweden
Posts: 47
Posted: 03:25pm 15 Feb 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 7585
Posted: 04:15pm 15 Feb 2025
Copy link to clipboard 
Print this post

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: Sweden
Posts: 47
Posted: 04:34pm 15 Feb 2025
Copy link to clipboard 
Print this post

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: Australia
Posts: 6230
Posted: 09:25pm 15 Feb 2025
Copy link to clipboard 
Print this post

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: Sweden
Posts: 47
Posted: 12:57am 16 Feb 2025
Copy link to clipboard 
Print this post

Reading from NS2009 now works / thanks Jim






/Peter63
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7585
Posted: 08:42am 16 Feb 2025
Copy link to clipboard 
Print this post

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: Sweden
Posts: 47
Posted: 03:11pm 17 Feb 2025
Copy link to clipboard 
Print this post

'
' 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 Kingdom
Posts: 1193
Posted: 05:48pm 17 Feb 2025
Copy link to clipboard 
Print this post

@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: Sweden
Posts: 47
Posted: 02:35pm 18 Feb 2025
Copy link to clipboard 
Print this post

  Quote  FYI: Always easier to read code when bracketed as such:


Thanks for the info, much easier to read code then

/Peter63
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7585
Posted: 03:01pm 18 Feb 2025
Copy link to clipboard 
Print this post

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
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025