Sending negative numbers (signed integer) using serial

Yessir

Member
Hi
I have been experimenting with a Robertsonics WAV Trigger for mixing audio tracks using the serial output from a Picaxe 08M2 to control it.
robertsonics WAV Trigger
I have been successful in controlling most functions on the such as Start / Stop / Pause / Resume / Loop tracks, however I am having problems controlling volume which I need to fade between tracks. The volume control for each track needs to be set between -70dB and +10dB using a signed integer. The serial protocol format from the online documentation is
  • VOLUME
  • Message Code = 0x05, Length = 7
    Data = Volume (2 bytes, signed int, -70dB to +10dB)
    Response = none
    Comments: Updates the output volume of the WAV Trigger with the specified gain in dB
    Example: 0xf0, 0xaa, 0x07, 0x05, 0x00, 0x00, 0x55
I have been able to send positive numbers over serial for the volume between 0 and +10dB, but I have not been able to send negative numbers. I appreciate that Picaxe can't handle negative numbers, but is there any way I can set the volume as a positive number and then add the negative sign before sending it as serial output?
 

AllyCat

Senior Member
Hi,
I have been able to send positive numbers over serial for the volume between 0 and +10dB,
What values have you needed to send for positive numbers? It's hard to see why two bytes are required to transmit integer values between -70 and +10. But the normal method of coding negative numbers is called "Twos Complement".

The PICaxe Program Editor does support negative (two complement) numbers to a limited extent. Try the following program in the Simulator (or with a real chip) for example.
Code:
#terminal 4800
#no_data
w0 = -10        ; Example value (note the - sign)
sertxd("W0= ",#w0," High byte= ",#b1," Low byte= ",#b0)
sertxd(cr,lf,"Binary Word =")
for b2 = 0 to 15
    b3 = w0 / 32768
    sertxd(#b3)
     w0 = w0 * 2
next b2
sertxd("%")
Which should produce:
Code:
W0 = 65526 High byte= 255 Low byte= 246
Binary Word =1111111111110110%
Cheers, Alan.
 
Last edited:

hippy

Technical Support
Staff member
Because volume is containable in a single signed byte value (-128/+127) turning that into a word simple requires extending the msb bit into the entire upper byte of the word. And because data is little endian, LSB first, I would suggest -
Code:
b0 = -20           ; Volume = -20dB ( can be -70 to 10 )
Gosub SendVolume

SendVolume:
  If b0 >= $80 Then
    SerOut TX, TX_BAUD, ( $F0, $AA, $07, $05, b0, $FF, $55 ) ; Negative
  Else
    SerOut TX, TX_BAUD, ( $F0, $AA, $07, $05, b0, $00, $55 ) ; Positive
  End If
  Return
That 'b0' can be replaced by any byte or word variable.
 

Yessir

Member
Hi Guys

Thanks for your help - Alans soulution really worked. I didn't realise that a variable couldbe set to a negative number.
Yessir.
 
Top