Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Magic: The Mini-magic Switchboard should I make it a kit?

Status
Not open for further replies.
blueroomelectronics said:
I wonder what the playing card variation trick is?
I would think it is a same song second verse sort of thing.

In the original trick the operator teaches the machine the order of the bulbs.

A good magician can ensure that he knows what cards people draw with various methods.

If the operator knows what cards (or products) people hold it is a simple matter to light the bulb that corresponds to the switch keyed to what they hold.

Could be wrong.
 
possibly something like a Dallas 1-wire memory chip? The magnet and screw holders to ensure a good contact, for the switches you could then use the case as the pickup.
 
I don't get you, why would you need a 1-wire memory chip?

The switch caps and bulbs aren't bugged you know.

It seems like you haven't read first three pages of this thread
 
Here's the code in PICBASIC as done on the dutch version, they also seem to sense if the bulbs are removed (according to the schematic) Would this be an advantage?
Code:
'****************************************************************
'*  Name    : Switchboard.BAS                                   *
'*  Author  : G.A. Nijland                                      *
'*  Notice  : Copyright (c) 2007                                *
'*  Date    : 19-08-2007                                        *
'*  Version : 1.0                                               *
'*  Notes   : This software is distributed as is without any    *
'*            warranty under the GNU GENERAL PUBLIC LICENSE.    *
'*            Please read 'GPL-3.0.TXT'                         *
'****************************************************************

    Device 16F628A
    Config INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
    
    ALL_DIGITAL = true
    XTAL = 4
    'PORTB_PULLUPS 
    ' LET OP: Gebruik voor deze versie nóóit de PULLUPS.
    ' Daardoor werkt het detectiemechanisme van een losgedraaide bulb niet meer.
    ' De switches hebben (helaas) een eigen pull up weerstand.
    ' Misschien de volgende versie...

    Include "..\()library\INT_SYMBOLS.bas"

    'Een paar hulpsymbolen voor tellen van interrupts
    Symbol  Prescaler = 256          'Let op: de prescaler wel goed instellen via PS0..2!!
    Symbol  PulsesPerSecond = (XTAL * (1000000/4)) / (256 * Prescaler)
    
    ' Namen voor de lampjes tbv in- en uitschakelen na leermodus
    Symbol  BulbOnbekend    = 0
    Symbol  Bulb1           = 1
    Symbol  Bulb2           = 2
    Symbol  Bulb3           = 3
    Symbol  Bulb4           = 4
    
    ' Symbolen voor in- en uitgeschakelde schakelaars (inverted)
    Symbol  SW_ON  = 0
    Symbol  SW_OFF = 1
    
    ' Poorten switches
    Symbol  Switch1 = PORTB.3
    Symbol  Switch2 = PORTB.2
    Symbol  Switch3 = PORTB.1
    Symbol  Switch4 = PORTB.0
    
    ' Lamp-detect poorten
    Symbol  LA1_In  = PORTB.4
    Symbol  LA2_In  = PORTB.5
    Symbol  LA3_In  = PORTB.7
    Symbol  LA4_In  = PORTB.6
    
    ' Uitgangen voor inschakelen lampjes
    Symbol  LA1_out = PORTA.0
    Symbol  LA2_out = PORTA.1
    Symbol  LA3_out = PORTA.3
    Symbol  LA4_out = PORTA.2
       
    ' State symbols voor besturing programma
    Symbol  LEERMODUS_SW1  = 1              ; Wacht op schakelaar 1
    Symbol  LEERMODUS_SW2  = 2              ; Wacht op schakelaar 2
    Symbol  LEERMODUS_SW3  = 3              ; Wacht op schakelaar 3
    Symbol  LEERMODUS_SW4  = 4              ; Wacht op schakelaar 4
    Symbol  SPEELMODUS     = 5              ; Schakelaars mogen willekeurig worden ingeschakeld
    
    ' Vertraginsinstellingen
    Symbol  RESET_DELAY = 10                ; # seconden voor de PIC reset naar leermodus 1
    Symbol  SLEEP_DELAY = 45                ; # seconden voor de PIC in slaap valt
    
    Dim Switch1_Target As Byte              ; Welk lampje gaat aan wanneer 1 wordt ingeschakeld?
    Dim Switch2_Target As Byte              ; Welk lampje gaat aan wanneer 2 wordt ingeschakeld?
    Dim Switch3_Target As Byte              ; Welk lampje gaat aan wanneer 3 wordt ingeschakeld?
    Dim Switch4_Target As Byte              ; Welk lampje gaat aan wanneer 4 wordt ingeschakeld?
       
    Dim BoardState  As Byte                 ; In welke state zitten we nu?
    Dim ResetCount  As Byte                 ; Teller voor terugschakelen naar leermodus sw1.
    Dim SleepCount  As Byte                 ; Teller voor in slaap vallen
    Dim SecDelay    As Byte                 ; Tellertje voor bijhouden wanneer 1 sec voorbij is 
    
    Dim SwitchTarget As Byte                ; Buffertje voor inschakelen lampje (parameter). Op basis
                                            ; van de waarde hierin, gaat één van de lampjes aan of uit.
    Dim SwitchStatus As Bit                 ; IDem...                                            
    
    Dim SwitchState As Byte                 ; De toestand van de schakelaars
    Dim SwitchStateOld As Byte              ; De toestand van de schakelaars 'de vorige keer'
    Dim LampState   As Byte                 ; De toestand van de lampjes
    Dim LampStateOld As Byte                ; De toestand van de lampjes 'de vorige keer'
    
    ' Interrupt vlag(gen)
    Dim FlagSeconde As Bit                  ; Er is een seconde verstreken
    
  
'-------------------------------------------------------------------------------
ProgramStart:
    on_interrupt    HandleInterrupt  
    GoTo    Main
        
'-------------------------------------------------------------------------------
HandleInterrupt:
    If T0IF = 1 Then
        Dec SecDelay
        If SecDelay = 0 Then
            SecDelay = PulsesPerSecond
            FlagSeconde = 1
        End If
        T0IF = 0
    End If
    
    'RB4..7 interrupt on change werkt helaas (nog) niet...
    'In het hoofdprogramma worden de switches en bulbs 'handmatig' afgetest.
    
HandleInterrupt99:    
    Context Restore        
    
'-------------------------------------------------------------------------------  
Main:
    ;  Hardware configuratie van de PIC
    ; Poorten instellen voor gebruik van de lampjes en schakelaars  
    ;        76543210
    TRISA = %00100000                       ; PORTA.5 input (MCLR), de rest output (lampjes schakelen)
    TRISB = %11111111                       ; Alle PORTB input (schakelaars en lampjes)
    
    Clear                                   
    DelayMS 100                             
    
    ; Interrupt flags zetten.
    GoSub   ConfigInterrupts
    
    ; Board reset
MainReset:    
    GoSub   SleepTimerReset
    GoSub   BoardReset

'-------------------------------------------------------------------------------  
    ; Hier start de centrale verwerkingslus.
    ; Hoe werkt dit:
    ; Afhankelijk van de state van het programma, voeren we acties uit.
    ; In de leermodus leren we achtereenvolgens welke lampjes bij welke schakelaars
    ; horen. Als we klaar zijn met 'leren', mogen de schakelaars willekeurig worden
    ; ingeschakeld.
    ; Als we een lampje losdraaien, dan moeten we de leermodus opnieuw starten.
    ; Want dan zijn er waarschijnlijk lampjes verwisseld. Dus de status van de lampjes
    ; controleren we regelmatig.
    ; Wanneer er 10 seconden geen actie is geweest doen we ook een reset van de leermodus.
    ; Dit is omdat we mogelijk de dopjes omgewisseld hebben. En dan moeten we die ook
    ; weer aan nieuw lampjes toekennen.
    ; Let op: deze reset doen we alleen als er géén schakelaar is omgezet!
    ; Telkens wanneer een schakelaar wordt ingeschakeld, doen we een reset van deze 
    ; 10-secondenteller. Want dan zijn we bezig met leren of 'spelen'!
    
    While SleepCount > 0
    
        ' 1. Haal de state van de schakelaars en lampjes op
        GoSub   GetExternalState
        
        ' 2. Als er met tenminste één van de lampjes iets is gebeurd, dan terug naar leermodus.
        '    We hoeven hier geen ontdendering te doen. Want of we nu een lampje uit- of indraaien
        '    en hoe vaak er 'dendert', pas bij overzetten van schakelaars wordt de volgorde
        '    bepalend. En dan hebben we toch weer een stabiele situatie.
        '    NB: lampjes wel goed vastdraaien :-)
        If LampState <> LampStateOld Then

            'Debug modus: als een lampje wordt losgedraaid, kort knipperen.        
            'LA4_out = 1     ' @@@@
            'DelayMS 250
            'LA4_out = 0
            
            GoSub   SleepTimerReset     'Als een lampje wordt los- of vastgedraaid, dan reset sleep timer
            GoSub   StartLeermodus      'We starten weer van voren af aan met de leermodus
            LampStateOld = LampState    'Tbv het opmerken van de volgende verandering
        End If
        
        ' 3. Als er een schakelaar is overgehaald, dan moeten we drie dingen doen:
        '    a. Ontdenderen
        '    b. Controleren of we in de leermodus zitten.
        '       Zo ja, dan bij inschakelen van een nieuwe schakelaar, deze bij het
        '       het lampje vastleggen en de leermodus.
        '       Bij alleen uitschakelen doen we in de leermodus niets.
        '    c. Het bijbehorende lampje in- of uitschakelen
        If SwitchState <> SwitchStateOld Then
        
            'Debug modus: laat zien dat de schakelactie 'gezien' is.
            'LA3_out = 1     ' @@@@
            'DelayMS 250
            'LA3_out = 0
            
            GoSub   SleepTimerReset     'Als een schakelaar wordt bediend, dan reset sleep timer
            DelayMS 5                   'Ontdendering 
            
            ' Als we nog niet in speelmodus zitten, moeten we de schakelaars 'leren'
            If BoardState <> SPEELMODUS Then GoSub AfhandelenLeermodus
            
            GoSub   LampjesTonen            'Lampjes aan of uit            
            SwitchStateOld = SwitchState    'Tbv het opmerken van de volgende verandering
            GoSub ResetCounterReset         'En de reset uitstellen
        End If
                
        ' 4. Tot slot de tijd-afhankelijke dingen doen.
        '   a. Controleer of we de 10-seconden reset moeten doen
        '   b. De sleep-timer ook aflagen zodat bij langere tijd geen actie we stroom kunnen besparen.
        If FlagSeconde = 1 Then
            FlagSeconde = 0
            GoSub CheckResetNaTijd
            ' En de sleep timer bijwerken
            Dec SleepCount
        End If
    Wend
    
    'Als we hier aankomen, dan zitten we in sleepmodus
    GoSub   SleepKnipper
    
    'Alle poorten laag
    PORTA = 0x00
    PORTB = 0x00
    
    'We reageren alleen op een RB0 verandering, maar geen interrupt geven.
    '(zie datasheet)
    GIE = 0
    INTF = 0
    INTE = 1
    INTEDG = 0      ' RB0 ontwaken bij 'laag'
    
    Sleep
    
    INTF = 0
    INTE = 0
    GIE = 1
    
    'We gebruiken schakelaar 4 voor het wakker worden (afhankelijk van de config).
    'Dus lampje 4 aanzetten om te laten zien dat we 'wakker' zijn én
    'wachten tot schakelaar 4 weer is uitgezet.
    DelayMS 5                           'Ontdenderen
    LA4_out = 1
    While Switch4 = 0
    Wend
    DelayMS 10                          'Ontdenderen
    LA4_out = 0    
    GoTo    MainReset                   'We beginnen weer van voren af aan...
    
'-------------------------------------------------------------------------------  
SleepKnipper:
    'Knipper een paar keer met lampje 4
    '(voornamelijk bij 'in slaap vallen')
    LA4_out = 1
    DelayMS 250
    LA4_out = 0
    DelayMS 250
    LA4_out = 1
    DelayMS 250
    LA4_out = 0
    DelayMS 250
    Return
    
AfhandelenLeermodus:
    'Hier gebeurt het echte werk. Afhankelijk van de status controleren we welk
    'lampje we aan welke schakelaar moeten koppelen.
    'Maar dat doen we alleen als we in de leermodus zitten.
    'We bepalen eerst welke lamp we nog moeten vastleggen. Dat doen we door te kijken
    'naar hoeveel switchtargets we al hebben vastgelegd.
    SwitchTarget = Bulb1
    If Switch1_Target <> 0 Then Inc SwitchTarget
    If Switch2_Target <> 0 Then Inc SwitchTarget
    If Switch3_Target <> 0 Then Inc SwitchTarget
    If Switch4_Target <> 0 Then Inc SwitchTarget
    
    'Switchtarget bevat nu het lampnummertje.
    'Nu alleen nog kijken welke schakelaar er is geschakeld.
    'Let op: als van deze schakelaar de switch-target al is ingevuld, dan vullen we die
    'uiteraard niet nog een keer in!
    'Dus we kunnen in de leermodus ook alle lampjes achter elkaar aanzetten. Dus een voor
    'een inschakelen is niet per so noodzakelijk!
    '
    'Controles:
    ' - is de schakelaar ingeschakeld.
    ' - indien nee, overslaan
    ' - zo ja, heeft die al een doel-lampje?
    '   - indien ja, dan deze switch overslaan.
    '   - indien nee: deze invullen en terugkeren.
    If Switch1 = SW_ON Then
        If Switch1_Target = BulbOnbekend Then
            Switch1_Target = SwitchTarget
            Inc BoardState
            Return
        End If    
    End If
    If Switch2 = SW_ON Then
        If Switch2_Target = BulbOnbekend Then
            Switch2_Target = SwitchTarget
            Inc BoardState
            Return
        End If    
    End If
    If Switch3 = SW_ON Then
        If Switch3_Target = BulbOnbekend Then
            Switch3_Target = SwitchTarget
            Inc BoardState
            Return
        End If    
    End If
    If Switch4 = SW_ON Then
        If Switch4_Target = BulbOnbekend Then
            Switch4_Target = SwitchTarget
            Inc BoardState
            Return
        End If    
    End If         
    Return
    
LampjesTonen:
    'Afhankelijk van welke schakelaars er zijn ingedrukt, schakelen we lampjes in.
    'We moeten daarbij steeds het lampje schakelen, dat er op basis van de 'leermodus' bij hoort.
    SwitchTarget = Switch1_Target: SwitchStatus = Switch1: GoSub SwitchBulb
    SwitchTarget = Switch2_Target: SwitchStatus = Switch2: GoSub SwitchBulb
    SwitchTarget = Switch3_Target: SwitchStatus = Switch3: GoSub SwitchBulb
    SwitchTarget = Switch4_Target: SwitchStatus = Switch4: GoSub SwitchBulb
    Return
    
SwitchBulb:
    'We krijgen de geinverteerde status binnen (veroorzaakt door de 'pull down' van de switches).
    'Dus 'hoog' is eigenlijk lampje uit. Daarom inverteren we die status hier weer.
    SwitchStatus = SwitchStatus ^ 1
    
    'Afhankelijk van de waarde in SwitchTarget gaan we een lampje schakelen.
    Select SwitchTarget
        Case Bulb1: LA1_out = SwitchStatus
        Case Bulb2: LA2_out = SwitchStatus
        Case Bulb3: LA3_out = SwitchStatus
        Case Bulb4: LA4_out = SwitchStatus
    End Select
    Return
                
GetExternalState:
    ' We gaan de status van de lampjes en schakelaars ophalen.
    ' Beide zitten op PORTB, dus die kunnen we ineens ophalen.
    ' De lampjes zitten in de hoge 4 bits. Dus die moeten we eruit filteren
    ' Daarna de schakelaars filteren op de 4 lage bits.
    SwitchState = PORTB
    LampState   = (SwitchState >> 4) & 0x0F
    SwitchState = SwitchState & 0x0F
    Return
            
CheckResetNaTijd:
    'Controler of we een aantal seconden niets hebben gedaan.
    'Als dat zo is, dan resetten we de leerodus.
    Dec     ResetCount
    If ResetCount = 0 Then GoSub StartLeermodus 
    Return

BoardReset:
    'Alle lampjes uit forceren
    LA1_out = 0
    LA2_out = 0
    LA3_out = 0
    LA4_out = 0    
    ; We beginnen met de leermodus
    GoSub   StartLeermodus
    Return
    'NB: de gosub en return kunnen eventueel worden weggelaten.
    'Maar als er vanwege debuggen statements bijkomen, is dat weer minder handig...
    
StartLeermodus:
    BoardState = LEERMODUS_SW1          ' De leermodus begint bij switch 1
    Switch1_Target = BulbOnbekend       ' We weten nog niet wat we inschakelen.
    Switch2_Target = BulbOnbekend       ' ...
    Switch3_Target = BulbOnbekend       ' ...
    Switch4_Target = BulbOnbekend       ' ...
    GoSub   ResetCounterReset           
                                        
    Return    

ResetCounterReset:
    ; Start opnieuw met tellen voor reset
    SecDelay = PulsesPerSecond          ' Interrupt delay weer op maximum zetten
    ResetCount = RESET_DELAY            ' Secondenteller ook weer op maximum.
    FlagSeconde = 0                     ' En wachten op nieuwe seconde-interrupts
    Return
    
SleepTimerReset:
    SleepCount = SLEEP_DELAY
    Return       
       
ConfigInterrupts:
    ; Timer 0: we werken op 4MHz, dus met maximale prescaler zo'n 15 interrupts per seconde
    GIE  = 0                            ' Effe geen interrupts
    PSA = 0                             ' Prescaler voor Timer0   
    PS0 = 1                             ' ...
    PS1 = 1                             ' ...
    PS2 = 1                             'Prescaler 111: maximale waarde van 256.
    T0CS = 0                            'Timer0 werkt op de interne clock.
    TMR0 = 0                            ''Harde reset' van timer0.
    T0IE = 1                            'Timer0 interrupts ingeschakeld
    SecDelay = PulsesPerSecond          'Begin met aftellen voor 1 seconde   
    GIE  = 1                            'Go...
    Return
        
    End
 
In the video when they ran with the first bulb missing the operator flipped the switch for the missing color saying something like "of course the missing bulb will not light". I JUST happened to be the first bulb so it worked out OK.

It could be harder to pass it off in other cases. Sensing the the bulbs would be advantageous.

Also they have a dip switch for settng modes. That could be handy if one wanted to get fancy. What do you think?
 
Well I guess you might as well build it right. We've got the free I/O and it can still be built with or without the current sense.
As for the DIP switch that's so old school, we could add a configuration jumper and use the switches to set the mode(s)

So let's reshuffle things a little
PORTA 0-3 the lamp drivers
PORTA 4 setup jumper
PORTA 5 MCLR
PORTA 6 mode/setup LED
PORTB 0-3 the current sense inputs
PORTB 4-7 the switches

PS don't really need a power LED
 
blueroomelectronics said:
Well I guess you might as well build it right. We've got the free I/O and it can still be built with or without the current sense.
As for the DIP switch that's so old school, we could add a configuration jumper and use the switches to set the mode(s)

So let's reshuffle things a little
PORTA 0-3 the lamp drivers
PORTA 4 setup jumper
PORTA 5 MCLR
PORTA 6 mode/setup LED
PORTB 0-3 the current sense inputs
PORTB 4-7 the switches

PS don't really need a power LED
I agree regarding the power LED and the DIP switch.
It may take a bit of doing to lay it out single sided with the added IO but I will give it a try.
 
blueroomelectronics said:
Nice photo with PIC from the Dutch forums
Looks like they've used painted wooden drawer knobs to slip over the bat handles of the switches.
 
Just remembered, RA3 is open collector on a 16F628A, so lets move the lamp on RA3 to RA7 *makes for a fun program too :)
Also skip the current sense stuff, I can't see any real advantage.
 
blueroomelectronics said:
Just remembered, RA3 is open collector on a 16F628A, so lets move the lamp on RA3 to RA7 *makes for a fun program too :)
Also skip the current sense stuff, I can't see any real advantage.
The 628A datasheet says
RA4 is a Schmitt Trigger
input and an open drain output. Port RA4 is multiplexed
with the T0CKI clock input.
Did not see where RA3 was open collector.

I do not care for the way the others did the bulb sensing. We will do the first board without. If we find that we would like to have it I will cut another board and use the ADC to do the sensing.

The 16F88 and and 16F628A should both work with the current layout.

If we want to program multiple modes switching between them can be done with the existing 4 switches. A magic combo/sequence of switches will put it into the program select mode.
 
You don't need to sense current to know if a bulb is present or not. Just put 10k resistors across the transistors and connect the collectors to spare inputs. When the bulb is off the input will be high if the bulb is present, low if removed. No need for any ADCs.

Mike.
 
I am glad to know that. It is just a pull down Doh! :D

I am trying to make the board easy for everyone to etch and build. So far SS with no jumpers or traces between pins. It looks like I can add the resistors but it will require 4 small jumpers. I guess that is not so bad.

But as Bill said I do not think they would add much.

To skip a bulb the operator says flips the switch for the empty socket and says " as you would expect flipping the COLOR switch does zip since its bulb is missing".

If you added the sensing you could maybe do away with that. I am not sure it is worth it.
 
Being able to sense if a bulb has been absent is so that you know when a new sequence needs to be inputed. This I believe is a better way than using a timer and probably how the original worked. The only time no bulbs are removed is right at the end of the video and just prior to that the magician does a particular sequence which I assume resets the program (from memory I think it is simply right to left).

Mike.
 
Hi,
For PIC16F628A, see PCON register to select two different internal RC oscillator. For PIC16F88, see OSCCON register to select many different internal RC oscillator.
 
Pommie said:
You don't need to sense current to know if a bulb is present or not. Just put 10k resistors across the transistors and connect the collectors to spare inputs. When the bulb is off the input will be high if the bulb is present, low if removed. No need for any ADCs.

Mike.

Hmm, I'll have to try it. Easy enough to add and can be ignored. It will draw current and make the addition of a power switch nessary. Unless the resistors are connected to RA3 to act as a programmable GND.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top