Switching issues

Jack Burns

New Member
Here is the prototype motor control picaxe PCB mounted on the motor connections PCB, next to the box is the previous 555 timer board
Thanks for the photo, it’s good to see your project advancing.
Would you be able to post the latest code, as I would be interested to see how much it has changed since the project started.
 

Rampz

Well-known member
Starting point

Code:
#picaxe 08m2
#no_data
setfreq m8   ' i set to 8mhz to see if it would help
    symbol green = 4   'pin c4
    symbol light = 400  'wait 400ms
    symbol btn = pinc.3   'pin c3
 
main:
    if btn = 1 then
    high green   ' turn on green led
    pause light   ' wait 400ms
    low green     ' turn green led off after
endif
goto main

After much help from several people

Code:
#picaxe 08m2
SetFreq M16


' Code snippets from Rampz, Goeytex & Jack Burns




#no_data
#terminal 19200

'.----------------------------.
'| Constants                  |
''----------------------------'
symbol BTN = PinC.3  '// Tilt Switch
symbol btn1 = PinC.1 ' memory recall button
symbol BTN2 = PinC.5 ' tilt switch reset switch, new xxxx
Symbol LED = C.4  ' mosfet output
Symbol LED2 = C.0 'changed back, battery volt read message gives a heartbeat effect once a second very useful
symbol released = 0 'added
Symbol Pressed = 1
Symbol LowBattLevel = 104 ' Low voltage threshold x 10 (104 = 10.4v)
Symbol AvgCount = 10 ' Number of ADC readings to be averaged when calculating battery voltage
Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
Symbol MinRunTime = 501 '// 501 = 400 ms approx.  Adjust this value to change delay time after button released
Symbol LowBattDuration = 10 'set at 10 seconds
Symbol ChargeReadInterval = 4000 ' 4000 = 1 sec @ 16Mhz Take a reading every second
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600
Symbol ChargeReadCount = 20 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 115 'battery on again voltage 115 = 11.5v

'.----------------------------.
'| Variables Used             |
''----------------------------'
symbol ReserveB1 = b1       ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB2 = b2       ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB3 = b3       ' Used in "MeasureBatteryVoltage" routine
symbol Counter = W2         ' Used in several places
symbol ADCvalue = W3        ' Used in "MeasureBatteryVoltage" routine
symbol ADCavg = W4          ' Used in "MeasureBatteryVoltage" routine
symbol Volts = W5           ' Used in several places
symbol VmonCount = W6       ' Used in battery monitoring loop
symbol LowBattCount = W7    ' Used for testing batt low for 10 seconds
symbol stallfaultcount = W8 ' counter for how many times stalled
symbol FlashCount = W9      ' Put this line at start of main code.
symbol LVDfaultcount = W10  ' counter for how many times low voltage disconnect happened
symbol C5counter = W11      ' counter to make C5 an input after 30 seconds


init: ' initialisation code
 
  for c5counter = 1 to 120
      pause 1000
      next c5counter
  disconnect

sertxd("coding by Rampz, Goeytex and Jack Burns V3:04/12/21",13,10) 'heading main users involved in code
read 0,WORD stallfaultcount ' To fill counter with previous faults after power fail
read 2,WORD LVDfaultcount ' To fill counter with previous faults after power fail

MAIN:
if btn1= released then 'added to check btn1 during main program, altered to high going low
    sertxd("Memory Recall, LVD then Battery Fail",13,10) 'added to display on terminal
    sertxd("   (stallfaultcount: ",#stallfaultcount,")",13,10) 'as above
    sertxd("   (LVDfaultcount: ",#LVDfaultcount,")",13,10) 'as above
   
    gosub memoryrecall 'added to send to memory recall if btn1 pressed
end if 'added as required

  IF BTN = Pressed then
      sertxd("Tilt switch operated",13,10)
        High LED
      StartCounter:
      Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
        '// If here then switch released
      '//  Time Out after 400 ms (however, no delay if motor was previously stalled)
      '// If another Press detected then reset timer
      Do While Counter > 1   
          Counter = Counter - 1
          If BTN = Pressed then 'start over
            Goto StartCounter
          END IF
    Loop
        sertxd("Timed out",13,10)
      LOW LED
      END IF     
    ' Now measure battery voltage approx once a second
    inc VmonCount
    if VmonCount>1000 then ' 1000 = approx 1 sec.  Measure battery voltage approx once a second
            VmonCount = 0
            gosub MeasureBatteryVoltage
            sertxd("Main Loop - Battery level: ")
            gosub ShowVoltage
            sertxd("   (LowBattCount: ",#LowBattCount,")",13,10)
            if Volts <= LowBattLevel then ' Set at 10.4 Volts in "Constants" section
                inc LowBattCount
                if LowBattCount > LowBattDuration then ' approx 10 seconds
                        gosub LowBatteryVoltage
                end if       
            else
                LowBattCount = 0 ' reset count if battery doesn't stay low for specified duration
            end if
    end if
GOTO MAIN:

MotorStalled:
    sertxd("Motor Stalled",13,10)
  
    stallfaultcount = stallfaultcount + 1 ' added
   write 0,WORD stallfaultcount ' This stores the "stallfaultcount" in EEPROM location 0
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf)
        low LED '// Turn motor drive off
    high LED2 '// Turn fault light on
       
    do : loop while BTN = pressed and btn2 = released '// Wait for switch to be released, btn2 = released resets motorstalled condition
     
    '// If here then switch has been released or btn2 pressed
    low LED2 '// Turn fault light off
        sertxd("Tilt switch has now reset",13,10)
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
    
MeasureBatteryVoltage:
        '// Measure average voltage over 10 readings.
        ADCavg = 0 'Initialise to 0
        for b1 = 1 to AvgCount 'adjust above for readings to average
            ReadADC10 C.2,ADCvalue
        ADCavg = ADCavg + ADCvalue
        next b1
        ADCavg = ADCavg / AvgCount
        ' Convert ADC Value to Voltage
        Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
      'volts = volts *65    ' correction needed to make 102
      'volts = volts /64    ' read 104
        Volts = Volts *16      ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
        Volts = Volts /100 ' Reduce to 3 digits
        '// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
        return
   
    ShowVoltage:
        BinTOASCII Volts, b3,b2,b1 : IF  b3 = "0" THEN : b3 = " " : ENDIF' leading zero blanking
        Sertxd (b3,b2,".",b1," Volts")  ' 0.1 resolution XXXremove in normal operationXXX
        return

LowBatteryVoltage:
for b22 = 1 to 10 'flash C0 10 times when LVD fault detected
    high led2
    PAUSE 200
    low led2
    PAUSE 500
next b22   

LVDfaultcount = LVDfaultcount + 1
write 2,WORD LVDfaultcount ' This stores the "LVDfaultcount" in EEPROM location 2
sertxd("LVDfaultcount: ",#LVDfaultcount,13,10)
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (") ' XXXremove in normal operationXXX
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 11.5V",13,10) ' XXXremove in normal operationXXX
            pause 4000 ' wait 1 second between readings
        loop until Volts >= highbattvolt 'see symbols above was (115)
        '// Battery voltage has now reached upper level
        sertxd("Battery has reached 11.5v ")
        gosub ShowVoltage
        sertxd(" - Now charging for 1 hour",13,10)
        '// Now wait an hour while battery continues to charge
        '// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
        Counter = ChargeReadCount
        do
            gosub MeasureBatteryVoltage
            sertxd("Battery level: ")
            gosub ShowVoltage
            sertxd(" - Charge time remaing: ",#Counter," Seconds",13,10) 'was cr,lf
            pause ChargeReadInterval ' Time between voltage readings while charging
            dec Counter
        loop while Counter > 0
        LowBattCount = 0 ' Reset time count for low battery voltage
        return
     
Memoryrecall:
read 0,WORD stallfaultcount
FlashCount = stallfaultcount     'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
pause 10000
read 2,WORD LVDfaultcount
flashcount =  LVDfaultcount  'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
stallfaultcount = 0 'clears counters in ram but not eeprom
write 0, stallfaultcount ' clear counter in eeprom
LVDfaultcount = 0 'clears counters in ram but not eeprom
write 2, LVDfaultcount ' clear counter in eeprom
return

     
'info
     
'Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
     
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600 (currently 20 seconds)
'Symbol ChargeReadCount = 20 ' Normally 3600 readings while battery charges
So pcb made and tested in the way it will be used, most timers are still as test times, i still need to looking to recovery rates of the battery i am using to determine how long to wait when when voltage reaches 11.5v that there is enough charge to allow the motors to start working again, i also need to monitor battery voltage and determine the voltage at which the above should start counting

You will see i added a correction for read battery voltage because the read voltage was 0.2v from what it should be while using the AXE091 development board, when i used my own pcb with LDO 5v regulator and 0.1% smd resistors, i found i didn't need any correction.

So still loads of work to get it to where i want it.
 

Rampz

Well-known member
Starting to work on this some more looking at additional feature, at the moment C0 is used to show a heart beat apperance when in fact it is actually sending the battery voltage to the terminal in the editor PE6, so what is seen as the led being on is a burst of data.

My question then is can i use this same pin to send data to be read by a second PICaxe, maybe to display the read voltage as a kind of data string that could be read and locally displayed on a screen, and as the current code is, when we have a low voltage situation of a motor failed situation, those are being saved in a counter in the eeprom, and data is sent to the terminal, if i want to send that also is some kind of format to the second picaxe and be saved in an eeprom position and then be displayed on the same local screen.

I want to get my head around if this can happen and how, so i can design the pcb to include the hardware side for future development without having to keep changing the pcb to suit

The items i would like to be able to send is mainly based around low voltage cut off and stall condition, so the start and finish of these conditions which currently display on the terminal if connected, additional useful information might be actual measured voltage at the motor drive

The main reason for asking is because the future development will be to stop the clock during a fault condition

I have run out of pins so have to make additional use of C0 as currently doing, the comms only needs to be one direction i think, an i understand that during a code download it could upset the receiving end, can 2x PICaxe's be coded so this data string is different to any other data transfer, so the receiving picaxe understand the difference etc?

The receiving PICaxe would ultimatley receive data from 1 to 3 08m2's, if all i can send is fault data then thats fine, i would expect that the receiving PICaxe receives data on seperate pins from each remote 08m2, i'm busy looking through the forum for info, looks like i would in each case need to maybe hold C0 high for a few ms so the receiving one knows something is coming?
 
Last edited:

Rampz

Well-known member
Another thing i want to look at it is, as a result of work on the tilt switch test rig, we all felt that sensing when the tilt switch turns off is cleaner than switching on, this was confirmed by testing on the test rig, current code that deals with the tilt switch turning on is:

Code:
IF BTN = Pressed then
      sertxd("Tilt switch operated",13,10)
        High LED
      StartCounter:
      Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
        '// If here then switch released
      '//  Time Out after 400 ms (however, no delay if motor was previously stalled)
      '// If another Press detected then reset timer
      Do While Counter > 1   
          Counter = Counter - 1
          If BTN = Pressed then 'start over
            Goto StartCounter
          END IF
Is it as simple as altering
IF BTN = Pressed then
to
IF BTN = Released then

and later
Do : Loop while BTN = Pressed and Time < MaxRunTime
to
Do : Loop while BTN = Released and Time < MaxRunTime

and then
If BTN = Pressed then 'start over
to
If BTN = Released then 'start over

This is how i would go about it in my mind, wondering if thats the best way to go about it?
 

Jack Burns

New Member
Is it as simple as altering
IF BTN = Pressed then
to
IF BTN = Released then

and later
Do : Loop while BTN = Pressed and Time < MaxRunTime
to
Do : Loop while BTN = Released and Time < MaxRunTime

and then
If BTN = Pressed then 'start over
to
If BTN = Released then 'start over

This is how i would go about it in my mind, wondering if thats the best way to go about it?
That should work, however a similar change will also be required in the MotorStalled routine.
 

Rampz

Well-known member
So current position of this project, pcb's are ordered but due to China new year will be delayed, i have included a mini usb connector not for usb use but because it was a good solid connector, it will allow me to connect the oled screen and receive date over C.0, i will also connect C.5 so before my disconnect happens i can update the code through a 3.5mm jack mounted seperatly to the screen jack.

Then i would like to use a spare input on the oled screen kit to be the memory recall button and send a command using SERRXD i think to recall the faults and display them on the screen rather than flash the C.0 led as i currently do, i hope i can get it to send other setup data along with the version of code i am using etc.

I'm assuming i need to monitor the C.5 pin after the disconnect has been sent for any incoming command, not sure from here as how to get it to ask for certain data, i have read that its best to do that 1 byte at a time leaving a pause, can't get my head around how the picaxe receives the command and then what goes to a subroutine? like i would do when monitoring an input?

The main reason for this is once i have programmed a picaxe i may well forget what version of code is in it, and since it can't be extracted etc, i'm thinking if i can get it to output this data to an oled screen it can be read and updated if need be.

Can't find any code examples doing this kind of thing? Will be trial and error when i get the pcb built

I suppose i am wondering what commands can be sent between 2 picaxes, just read data from a remore location? or do more, maybe send the program to a "goto" an area where it can write all the info i want to the oled screen, or do i collect all the data i want into the picaxe attached to the screen and then display it locally? Then there are values that are written in the "symbols" section that are used in the code, if i want to read this remotely, can i do that directly or do i need to put that data into a byte or word so it can be sent?
 

Attachments

Last edited:

AllyCat

Senior Member
Hi,
.... once i have programmed a picaxe i may well forget what version of code is in it, and since it can't be extracted etc, i'm thinking if i can get it to output this data to an oled screen it can be read and updated if need be. .... Can't find any code examples doing this kind of thing? Will be trial and error when i get the pcb built
That's easy to do; just include a PAUSE of few seconds at the start of the program and then SERTXD a "version number" string. That can even be "automated" by using one of the ppp_ (preprocessor) variables to indicate the filename and/or date, etc.. There are examples on the forum, and personally, at bootup I often output a measurement of the supply rail (using CALIBADC10) as a "sanity check" that the battery/supply is good (or when an "unexpected" Reset occurs).

Generally, I recommend NOT to use the DISCONNECT and/or SERRXD commands, there are just too may threads on the forum (over 50 in their titles alone) where the OP has encountered problems with the Hard Reset procedure. IMHO there are better ways to extend the number of inputs, using for example C.3 and/or C.0. Or use a 14M2 which is not much larger or more expensive and has greatly increased capabilities (about 4 times more RAM and TABLE EEPROM, etc.).

But if you feel you really MUST use C.5 as an input, then a trick I use is to increase the 10k input pull-down resistor to about 100k. Then, after the DISCONNECT or SERRXD command, arrange the program to activate the internal Weak Pullup resistor on C.5 (which pulls the pin high to indicate that the disconnect has occurred). Then use the desired "input control signal" (e.g. switch) to pull the pin Down via a diode, because that cannot prevent the PICaxe from (re-) booting after a power-up or reset. Alternatively, if the primary purpose of the program is to poll/receive serial data on C.5 (and to act accordingly) then it's easy to include an "escape" character such as Q (Quit) or X (eXit), to execute a RECONNECT and shut the program down in preparation for a new Program Download.

Cheers, Alan.
 

Rampz

Well-known member
at bootup I often output a measurement of the supply rail (using CALIBADC10) as a "sanity check" that the battery/supply is good
That's a really good idea Alan

Generally, I recommend NOT to use the DISCONNECT and/or SERRXD commands, there are just too may threads on the forum (over 50 in their titles alone) where the OP has encountered problems with the Hard Reset procedure. IMHO there are better ways to extend the number of inputs, using for example C.3 and/or C.0.
In my code currently when i cycle the power i set a time that runs for 20 seconds before the disconnect command is sent so that i have plenty of time to do a download, but i'm looking at freeing that pin up fo user serial data from the oled 18m2

That's easy to do; just include a PAUSE of few seconds at the start of the program and then SERTXD a "version number" string.
Yep that's i thought i could do regards version number etc, but if i want "symbol" like " Symbol LowBattLevel = 104" then i guess i need to write them to a location maybe in eeprom and then can send them to the 18m2 which in turn can display them? what i am ultimately trying to do is have the ability to alter a few Parameters from some push buttons on the spare inputs on the 18m2 that controls the oled, hoping to read all the values and display them, then have a routine on the 18m2 that allows me to scroll through each one and change the value if required then when back to the start write them back to the 08m2 eeprom for use in the code

I have some battery levels used in the code that i would like the ability to alter, a stall time, debounce time, the idea being that i can then make small changes without a laptop while at the top of a bell tower

I am just trying to do this step by step, like you say firstly at start up can write them to the oled, but would also be useful to be able to send a command on C5 while the code is running to receive a list of parameters

I'm really short on space or i could have gone to the 14m2 and had the extra inputs, if there will be some limitations in what i can do then fine, a lot of this is great if it can be done, saves having the user playing with code, hopefully reducing issues

if the primary purpose of the program is to poll/receive serial data on C.5 (and to act accordingly)
Yep i think this is where i am heading with this part, i was previously using it as an input, but as above could be better as user serial comms
 

lbenson

Senior Member
I'm really short on space or i could have gone to the 14m2 and had the extra inputs
You might look at the very compact surface mount 14M2. People have even sawed off the non-programming end of the 14M2 to make, as I recall, either a 12M2 or a 10M2. But you might lose a pin with a function you need.
 

Rampz

Well-known member
You might look at the very compact surface mount 14M2. People have even sawed off the non-programming end of the 14M2 to make, as I recall, either a 12M2 or a 10M2. But you might lose a pin with a function you need.
Wow that seems extreme, I would never thought of cutting a chip.

Since I already have the pcbs being made based on what I was doing previously I will have to push the 08m2 as far as I can, there will be future rework as the project progresses
 

David_Reynolds

Well-known member
There are also 2 sides to a PCB so it may be possible to fit the chip on one side and all the support to the opposite side. I have surface mounted standard chips by bending the legs out and surface soldering them, it avoids through holes with pins sticking out, after all the cost of the plated through holes is very minimal when ordering a PCB to be made.
 

Rampz

Well-known member
There are also 2 sides to a PCB so it may be possible to fit the chip on one side and all the support to the opposite side. I have surface mounted standard chips by bending the legs out and surface soldering them, it avoids through holes with pins sticking out, after all the cost of the plated through holes is very minimal when ordering a PCB to be made.
David yep i am using both sides as it is, the board is only 16mm x 30mm, it has a voltage regulator on it, 10 smd resistors, 08m2, small cap, 2 smd push buttons, i could fit a 14m2 smd i guess, but prefer through hole for chips where i can, this board is on 2 rows of header pins on the motor drive board below and not much space to increase board size etc
 

Rampz

Well-known member
I have started to see if i can get the 14m2 in the pcb along with everything else, i'm sure like you say it would be the best way to go and give more programming space etc, i'm not very interested in try to go smd for picaxe rather stay will Dil size chips etc
 

hippy

Technical Support
Staff member
I have started to see if i can get the 14m2 in the pcb along with everything else, i'm sure like you say it would be the best way to go and give more programming space etc
If this still relates to a dual PICAXE setup where one controls an LCD display; using a 20X2 for the display driver, maybe both, would have advantages, not least its ability to do background serial receive.

Striving to use the smallest or cheapest PICAXE can often be a false economy though one appreciates some applications may have size constraints. Designs which can relax those constraints, such as a small master controller, a larger separate LCD controller, can sometimes help there.
 

Rampz

Well-known member
If this still relates to a dual PICAXE setup where one controls an LCD display
Hippy in my setup i wanted the screen as a maintenance tool that could be plugged into the main board and give out various details and any faults that has been recorded etc.

background serial receive
I have seen this mentioned would seem it would do what i want but never found much info about it? How do i use it? connections etc?
 

lbenson

Senior Member
>background serial receive

Connections are on the hserin and hserout pins. There's only a two-byte buffer on the M2 chips. Here's a sample of the code I use to pick up and handle incoming:
Code:
symbol command = b11

  hsersetup B2400_4, %00001000 ' input not inverted ("T"-bit2=0), disable hserout

do
  command = $FF ' non-valid command
  hserin command ' if no bytes ready, no change
'  serrxd command
  if command <> $FF then : sertxd("$",command) : endif
  if command >= "0" and command <= "9" then
    sertxd("!",command)
   select case command
    case "0" ' all off
       ' DO SOMETHING
' . . .
    case "9" ' report status
       ' DO SOMETHING ELSE
   endselect
  endif
' DO OTHER STUFF
loop
This takes ascii "0" through "9" as commands (but you can use any single characters)). With the hserin command, the value of the byte which receives the result of hserin will be unchanged if no background character has been received. I preset that value to $FF, which will never be a valid command, and then act if the value is different than that.

Typically, you don't need to use the hserout pin, so it can be set for normal use. If receiving from another PICAXE, you'll probably want the input to be "inverted".
 

hippy

Technical Support
Staff member
background serial receive
I have seen this mentioned would seem it would do what i want but never found much info about it? How do i use it? connections etc?
Basically it's a connection to the HSERIN pin then a case of issuing a HSERSETUP command. After that all bytes received go into the Scratchpad while the PICAXE is doing whatever else it is doing, and they can then be pulled out at leisure without missing any.

This allows for a much more relaxed communication regime when it comes to synchronising the master and display. The 20X2 has a 128 byte scratchpad which will often be enough, but the 28X2 has 1,024 which can make things even easier.

The https://picaxeforum.co.uk/threads/improving-the-axe133-oled-firmware.29710 thread is probably a good introduction to issues such as speeding up the AXE133 code and replacing the 18M2 used with a 20X2 using background receive.
 

Rampz

Well-known member
So moving on it seems i am best changing my 08m2 picaxe to maybe a 20X2, i'm sure it will do what i currently do, but now im looking to get any one or all the autodrive picaxes talking to a master, the master only needs to be able to receive data from a max of 3 others, and data being sent would be faults generally these being incrementing counters in the autodrives, with the master displaying these faults for each autodrive say on a 4 line oled and acting on info received, regards connections do i receive data from each slave on a seperate pin? 1 pin per picaxe? or do i look at I2C and have a bus type setup? Thank you Hippy looks like the scratchpad in the X2 range will be useful for this, just a case of working out the basis.

Currently the autodrives are running on 2 core flex taking power, i would look at making that a 3 core flex with the third core being a picaxe pin back to the master picaxe for data, these cables could be 3m long, i'm including this info in case it makes a difference as how to connect them

Edit
I really can't get my head around if communication using hserout can be just receive only slaves sending to master or does the master have to issue a request and then the slave respond?
 
Last edited:

hippy

Technical Support
Staff member
So moving on it seems i am best changing my 08m2 picaxe to maybe a 20X2, i'm sure it will do what i currently do, but now im looking to get any one or all the autodrive picaxes talking to a master, the master only needs to be able to receive data from a max of 3 others, and data being sent would be faults generally these being incrementing counters in the autodrives

I really can't get my head around if communication using hserout can be just receive only slaves sending to master or does the master have to issue a request and then the slave respond?
Communications can be bi-directional, a display slave can ask the master for data and the master can supply the data asked for. The advantage of HSERIAL on the slaves is the master can simply send out data without having to check a slave is ready to receive it. That greatly simplifies things.

In fact, the master could simply send out all its data all the time whether a display slave is connected or not. Display slaves would get all the data, display what they wanted to display, simply by connecting them to the master. No complicated protocols involved at all.

In this case it appears you have multiple masters sending to one display PICAXE. That should still be easy enough with each master sending all its data when asked to do so by the display PICAXE.

Which PICAXE chips to use is always hard to say. If a simple send everything scheme is adopted it may be possible to keep using 08M2 or other M2 as the masters. A send data on request could also work but that will depend on how much data there is; the more different requests there are the more code will be needed to determine and handle those requests.

The more a display PICAXE has to receive, the greater the benefits of having a larger ScratchPad, 28X2 instead of 20X2. That's sometimes a better choice even if not needed because it can avoid needing to know what is needed before being able to say. It's usually easier to downgrade at the end of a project than be forced to upgrade halfway through.

That can apply to all projects, so it may be best to have a 20X2 as the masters, 28X2 as the display slave for the prototypes. Then, when that's all working, you can decide if it can be reduced and whether that's worth it or not.
 

Rampz

Well-known member
The advantage of HSERIAL on the slaves is the master can simply send out data without having to check a slave is ready to receive it. That greatly simplifies things.
So Hippy in my case my Masters using 20X2 picaxe will send out on C.0 hserout to a slave display 28X2 am i able to use serveal pins as receive pins? Then the Masters can send when they want and it will all be received in the scratchpad?

The data being sent will be from 2x counters that i don't expect to ever get above 255 so will be 1byte each, maybe a voltage consisting of 2x bytes, a current reading also in 2x bytes i would think, for me the only time the counters need to update the display slave is if something changes count wise if it helps, current and voltage would be good to stay up to date.

The display slave would perform an action if either of the counters increment from any other the masters, which in normal operation they shouldn't

If a counter increments then we are in a fault situation and receiving subsequent messages isn't needed at that point, the slave would go to its sub section a perform a task which would involve a clock module and be time related

I'm trying to keep 1 data wire and supply between my masters and the display slave

Edit
Reading further it seems all Masters will output on HSEROUT and the display Slave will receive all data from all masters on the same HSERIN?

And I will need a 1K series resistor on all Master's hserout's ?

So how do you try and make sure all masters don't send at the same time when only using 1 wire?

And I would expect each Master will have an identifier or the slave won't know what's come from who?

Sorry for the continious questions, i want to get my head around it all both from a hardware and code point of view
 
Last edited:

PhilHornby

Senior Member
Currently the autodrives are running on 2 core flex taking power, I would look at making that a 3 core flex with the third core being a picaxe pin back to the master picaxe for data, these cables could be 3m long, I'm including this info in case it makes a difference as how to connect them
3m is too far for TTL-level signals - these really need converting to RS-232 (or V24 as I knew it in the 70's). Otherwise you'll find some data is lost - and some data is received that no one sent!.

In general, with this architecture, will it matter if messages aren't received properly? (if for example the receiver is too busy to retrieve them from the scratchpad, before they are overwritten).
 

Rampz

Well-known member
3m is too far for TTL-level signals
Thanks Phil i have just asked the question to the manufacturer but maybe 3m was too much i expect him to answer 2m, yep still over 4 times what the standard says for TTL ( He has replied that 2m is the max length for a cable, saying he has never had to extend one, also that often there is spare so it could be reduced to 1.5m he thinks)

Data i am sending:

The stall counter - this should't increment in normal use, but at same time i don't want a spurious number turn up or i would be acting on it falsely

The Low Voltage counter - doesn't matter so much about this, if this counter has incremented then the read volatge is at 10.4v and its a bit late to do anything, i can monitor battery status from the supply end and go do something if i am running on battery for too long

Local Current - i was hoping to send a reading for this but to be fair it can be done from the display end for each outgoing supply

Local Voltage - would be good to be able to read this, a small error from time to time won't matter

In conclusion the data being sent is not great with only the stall counter maybe needing some kind of error checking?

Another thought would i be better having 1 20X2 per autodrive all talking to the display maybe over internal I2C ?

I have started looking at Level Shifting if this is an alternative solution by boosting the transmission voltage with transistor either end to say 12v ?

The attached PDF was my attempt at some kind of level shifting
 

Attachments

Last edited:

lbenson

Senior Member
I know that 3+ meters for ttl serial is not recommended, but I've successfully sent and received 5V ttl serial over 50 feet of cat5/6 without noticing any errors. You may in any case want error checking.
 

PhilHornby

Senior Member
Another thought would I be better having 1 20X2 per autodrive all talking to the display maybe over internal I2C ?
That would introduce a new issue: that of inter-locking access to the display to prevent two Picaxe's trying to talk to it simultaneously.

I have implemented a similar 'multi-master' system for the Heating Control system in our holiday cottage. Autonomous Room Controllers send messages via HC-12 wireless, containing current temperature and battery voltage. They expect to receive an acknowledgment, which potentially includes a new temperature Setpoint for the room. There is (necessarily) a time-out on the exchange, whereupon the node retries. The messages contain a 'sequence number' and are CRC-protected. The central 20X2 maintains a data structure for each remote node, so it can track their status and mark them offline if they stop communicating. This 'database' is also used to update the LCD and Webserver (on a separate Picaxe). This is the only time-sensitive function the 20X2 has - and is dealt with, entirely within the Interrupt Service Routing (aka ISR). Other, lesser priority functions are implemented in the main program loop, other than the 'Setpoint updating' user-interaction (seen in a previous youtube video). There are a total of 8 interacting Picaxe's and the software took a fair amount of writing!

I have started looking at Level Shifting if this is an alternative solution by boosting the transmission voltage with transistor either end to say 12v ?
The attached PDF was my attempt at some kind of level shifting
I'm not qualified to comment on hardware designs, but personally, I would probably use MAX232A's, or their more modern replacements. Remember that the signals are referenced to 'earth' and so shielded cabling is in order.
 
Last edited:

PhilHornby

Senior Member
I know that 3+ meters for ttl serial is not recommended, but I've successfully sent and received 5V ttl serial over 50 feet of cat5/6 without noticing any errors.
I know I live in a 'glass house' in this respect, since I'm forever doing the things the wrong way and getting away with it ;). However, this is a commercial application and we probably have a duty to steer the OP to the 'correct' way of doing things :).

Professionally, I encountered a commercial setup that was sending serial data over 80+ meters of UTP (because everyone knows UTP is good for 100m ;) The application used the antique Bisync protocol, resulting in the connection being error-free. However, error-free didn't mean it actually worked! (The symptom they had was that the throughput was about 1 char per sec. :( and the application timed-out (The Bisync protocol was being heavily used to correct the myriad of errors that were encountered)). The use of 'Line Drivers', like these, fixed the problem.
 

Rampz

Well-known member
I know that 3+ meters for ttl serial is not recommended, but I've successfully sent and received 5V ttl serial over 50 feet of cat5/6 without noticing any errors. You may in any case want error checking.
Thanks Ibenson, if i can keep to say my max 2m with some form of error checking then then its going to be possible by the sounds of it, maybe best i look at a stranded cat5 cable and triple up my power pair and double up my data core and make it possibly a screened cable or just use a cat5 socket at my display position, making use of industry availble kit
 

PhilHornby

Senior Member
Cat 5 /UTP is intended for use with balanced/differential signals, like RS-423 or Ethernet. The issue with pushing the boundaries, is that you might find that the prototypes work, but not the field implementations. Or that some of the field implementations work ... and some don't...
 

Rampz

Well-known member
I know I live in a 'glass house' in this respect, since I'm forever doing the things the wrong way and getting away with it ;). However, this is a commercial application and we probably have a duty to steer the OP to the 'correct' way of doing things :).
Phil i am going to have to try it over my 2m and see what its going to be like, and try and work with it, i'm so limited on space, i could fit something but would have to build it into the existing pcb
 

PhilHornby

Senior Member
Bluetooth has some merit (despite my own disastrous experience in the aforementioned Heating Controller!). Once they're connected, the link is logically error-free - it's the 'getting them connected' that can be an issue!

You would have an immediate issue, in that the simple HC-05 style modules only allow a single connection at a time. There is also the question of current consumption when in this state (though I don't have a number for that). If you try and make them connect-on-demand as I did, you end up needing random back-offs before retrying or they all sit there in one big, uncooperative heap!
 
Last edited:

Rampz

Well-known member
Phil so i'm left having to choose the best of a bad job based on everybodies comments, looks like i will have to go for direct wire and get it working close and see what the effects are at 2m afterwards and try and work with it, decisions decisions and not much clue Lol, data transmission isn't something i thought i would ever be trying to do, i've ordered a second AXE091 and some 20X2 and 28X2 picaxe to start sorting something
 

PhilHornby

Senior Member
so I'm left having to choose the best of a bad job based on everybody's comments, looks like I will have to go for direct wire and get it working close and see what the effects are at 2m afterwards.
Low baud-rates and shielded cables are most likely to succeed in that scenario ...

The MAX232 approach is easily within your capabilities though :-
25251

The later versions allow the use of much smaller caps - and no doubt, there's a surface-mount version.
 

Rampz

Well-known member
The MAX232 approach is easily within your capabilities though :-
Phil will try with the first route but will look into the MAX232 solution and see if i can get it in somehow. I assume i will need 1 each end?

Seems there a few MAX3232 pcb's on ebay having a read up.

And i will only need data in 1 direction
 
Last edited:

PhilHornby

Senior Member
but will look into the MAX232 solution and see if I can get it in somehow. I assume I will need 1 each end?
Yes - it needs a pair per comms. line. (ISTR that there is a dual-version of the IC).

I've used this circuit before (it's from an 80's Serial Mouse!), but actually, it's more complicated to implement than the MAX232, and has some restrictions. (It's interesting though ;) )
 

Rampz

Well-known member
Yes - it needs a pair per comms. line.
Phil i only need data in one direction, but that was when i was using a 3 core flex, not ideal anyway, but moving to say a shielded cat5e patch lead as the interconnection, am i best having 2 ways data just for the sake of keeping it all balanced? 3 wires positve, 3 wires wires negative and a twisted pair for data?
 

mikeyBoo

Senior Member
Well, I worked in heavy industry for 30 years, so here’s what I have seen work:
RS232 (e.g. MAX232 +/-12v) in foil shield 1 end of shield grounded (or not). (9600baud @ 50ft usually not a problem)

Tach & power supply signals in drive panels tightly twisted with no shielding.
Always twist DC power supply +/- wires together (done easily by putting ends of wire in a vise & twisting with drill motor).

RS485 (differential) works fine for transporting serial data over long distances & it’s cheap to use.
e.g. DS75176B

What you often see (scope or data-acq) is that signals will start to bend on the leading edge as the frequency increases until they reach a point where they look like needle-points (think of a capacitor charging). Simply send a square wave (battery-powered generator) over the wires you’re going to use & you’ll be able to see your frequency limit pretty quickly.
 
Top