255 word Speech IC

newplumber

Senior Member
texas said:
Glad you're getting ready for your old age
Yes true ...always have to think ahead....just need to install a few more toilets for another 22 years
my phone is a android 6.0...and I tried messing with the video options but didn't seem to be my friend


hippy said:
How long are the segments and how many LED's did you use per segment in the end
Each segment is about 6.25" (158 mm) with 5 leds per segment ( i think my strip I cut was 150 rgb led per 5m)
the 1/8" plexi glass is about 1.5" (38mm) above the leds ...I used 3/4" plywood with router depths of 5/8" because I figured
at that routered depth then the led light wouldn't spread out so much...and it seems to work great
The plexi glass is covered with a cheap white pvc shower curtain ...with adhesive spray ...which was a real challenge
I will draw a schematic with details to make it clearer when I get a chance
 

newplumber

Senior Member
Here is simple drawing trying to show how I put it together
One thing I should mention is if a person was going to router out using wood
they would also need a 1/8 bit for the router to get into the corners and have
very steady hands because the routered channels are what you see for the segments
in other words ...you shouldn't router out the wood if you just
used a plate compactor :)
 

Attachments

techElder

Well-known member
Mark, based on your threat to create a 16 inch display, here are some amusing calculations ... :D

Assume this possibility: Write to one 60 LED strip to create one large seven-segment display with decimal point.

APA102 60 LED 1meter strip. Divide that in 7 segments to get 8 LEDs per segment with 4 LEDs left for a decimal point.

With 60 LEDs in 1 meter, that's about 16.67 mm pitch between LEDs.

Each segment has 8 LEDs for about 133.33 mm (5-1/4 inches) length of each segment. That's about a 10-1/2" display.

I'm thinking "Go big, or go home!" Double that up to get a 21 inch display! :D
 

newplumber

Senior Member
Nice calculations texas....someday I should try to build (forget the inch measurements!) lets measure in "FEET" display
Two problems for me that will rise up if i go bigger ....
#1 = the more apa102 leds..the slower it will take to update...of course then i would need to dial in on the pros
#2 = construction....although I can whip up some aluminum shells ...I would need to test what kind of light deflection covers would handle
the out side weather beatings
Now don't get me wrong....its on the planning shelf somewhere so heres my horrible idea (in the far future of course)
since I went from small digital display 3" total length to 48" total length.... it would be cool to build the biggest
display in my town...with RGB...and something like 10' in length ...48" displays ....I'm a dreamer but thinking
if I ever start up a store with a big front ...I would try to pull it off.
But back to reality ....I'm trying to get the mp3 to be my friend ....well after I take it out of the package and place it on a bread board :)
 

premelec

Senior Member
PEX!

I see APA102 strings inside white PEX tubing in your future...;-0 [I used some white PEX in an item I did - looked pretty good...] - better make it UV resistant PEX...
 
Last edited:

newplumber

Senior Member
good idea premelec ....never tried that (leds in pex) and true about UV..pex is horrible for that
well (cough) ...it can be good for UV if your into service work like me :)

Btw I have my mp3 player all hooked up with voice audio on the sd card and I'm getting no noise out of my headset
I'm using this code
Code:
;MP3 from data sheet
#picaxe 20M2
#No_data
#terminal 4800

Symbol tx  = B.6
Symbol rx = B.7
Symbol BUSY_PIN = pinC.2
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol cmd = b0
Symbol arg = w1 ; b3:b2
Symbol arg.lsb = b2
Symbol arg.msb = b3
Symbol varA = w2
Symbol mp3V = b6
mp3V = 20
Main:
High TX ; set TX pin high for idle high serial
Pause 2000
SerTxd("Starting", CR, LF )
SerTxd("Select microSD Card", CR, LF )
cmd = $09 : arg = $0002 : Gosub Send
Pause 4000
SerTxd("Set volume =  ",#mp3V, CR, LF )
cmd = $06 : arg = mp3V : Gosub Send
Pause 1000
For varA = 0 To 2
 SerTxd("Play MP3 folder song 000", #varA, CR, LF )
 cmd = $12 : arg = varA : Gosub Send
 Pause 3000
 'Do While BUSY_PIN = 0
 'Loop
Next
Sertxd("Done", CR, LF )
inc mp3V
goto main
Send:
 SetFreq BAUD_FREQ
 Pause 10
 SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
 SetFreq MDEFAULT
 Return
the mp3 player I ordered is
https://www.ebay.com/itm/UART-Control-Serial-MP3-Music-Player-Module-For-Arduino-YX5300-US-Seller/391707147944?ssPageName=STRK:MEBIDX:IT&_trksid=p2057872.m2749.l2649

I wonder what is the limit for the volume "$20" to "$40","$80","$200"?
back to testing
 

premelec

Senior Member
I think that unit is the same chip as in RevEds SPE035 unit - did you look at that PDF file? - a lot of detail on how to drive it... I haven't done it myself... yet...
 

newplumber

Senior Member
I have been studying it
http://www.picaxe.com/docs/spe035.pdf
on page 8
it shows in the first chart
picaxe output TX ---- connects------ to mp3 RX pin
I tried both ways
I have a brand new 32g sd card
and I did as the awesome pdf shows make a folder named MP3
and have all files inside that folder with names 0001.mp3
I'll keep learning how not to make sound :)
 

hippy

Technical Support
Staff member
The YX5300 you have is not the same as the DF Player Mini. The protocol seems to be similar but there may be some differences. Where files need to be placed on the SD card and how they need to be named may differ.

picaxe output TX ---- connects------ to mp3 RX pin
I tried both ways
I am not entirely sure what that means. What voltage are you running your PICAXE and MP3 player at ? Did you include the 1K current limiting resistor if using 5V for the PICAXE ?

If you have connected the PICAXE TX to the MP3 Player TX you may have damaged one or the other but hopefully not.

You are using the $12 command to play tracks which works for the DF Player Mini but doesn't seem to be included in the YX5300 datasheet I have. That datasheet is in Chinese so I can't say exactly what you should be using.
 

newplumber

Senior Member
Thanks Hippy I think I have it figured out
Here is the code that is working perfectly with the downloaded picaxe mp3 files (sounds out numbers 1 thru 9)
Code:
;Test MP3 
#picaxe 20M2
#No_data
let dirsB = %10000000

Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol cmd = b0
Symbol arg = w1 ; b3:b2
Symbol arg.lsb = b2
Symbol arg.msb = b3
Symbol varA = w2

Symbol tx = B.7 ' --->  to MP3 pin RX 
Symbol rx = B.6 ' --->  to MP3 pin TX 

High TX ; set TX pin high for idle high serial
Pause 2000
cmd = $09 : arg = $0002 : Gosub Send ' $0002 = SD card 
Pause 4000
cmd = $06 : arg = 20 : Gosub Send ' <-- Volume 0 to 30 
Pause 100

Do '========================Main Program============================
 For varA = 1 To 9
  cmd = $03 : arg = varA : Gosub Send 'play files 0001.mp3 to 0009.mp3 on sd card
  Pause 1000
 Next
Loop  

Send:
 SetFreq BAUD_FREQ
 Pause 10
 SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
 SetFreq MDEFAULT
Return
It will not play sound using
Code:
Do '========================Main Program============================
 For varA = 1 To 9
  cmd = [B]$12[/B] : arg = varA : Gosub Send 'play files 0001.mp3 to 0009.mp3 on sd card
  Pause 1000
 Next
Loop
hippy said:
If you have connected the PICAXE TX to the MP3 Player TX you may have damaged one or the other but hopefully not
me? damage something? no...never :) but i did hook it up backwards once and it still plays just fine (i think i got lucky)
I'm running the whole thing on 5 vdc with caps on the breadboard
I do like it(mp3) ...now I just have to throw the head set away and bring up the volume with some true speakers
I have I think 100+ lm386's which should do the job ...love the way google has images for all different schematics

That datasheet is in Chinese
thats funny....now you kinda understand how I look at data sheets in ENGLISH :)
 
Last edited:

newplumber

Senior Member
premelec said:
@newplumber - there is a good open source sound editor "Audacity" with which you can make versions with pitch changed but not tempo and record small selected bits from larger files etc.
this program is very cool ...easy to cut/paste and speed and etc thanks premelec
now i'm going to spend the rest of life making sounds :) (joking)
Another good site i seen for text to speech and download the mp3 file is
http://www.text2speech.org/
and you can throw it in Audacity and change pitch with speed of sound pretty cool stuff
I will draw up some schematic of my mp3 sound alarm in a bit for the big clock
only natural to adjust the volume to the size of digits :)
 

newplumber

Senior Member
Hi
Here is my first schematic I plan on using ...
If I was to use ...lets say 12 lm386s with 12 small speakers (I think my speakers are like 8 ohm +/- )
and instead of have a pot into each lm386 would each input signal be equal on the lm386
if I just used a resistor(5k) in line to each one (lm386) so each lm386 would be amped equal output to each of its speaker?
I will try some tests when i get back to my picaxe cave
The best part is all the speakers and lm chips of mine are just collecting dust so its good to
try putting some use to them
 

Attachments

Last edited:

techElder

Well-known member
I don't know what the output is on your MP3 player, but that is what would limit how many channels you add. All the pots in parallel are your load ... more or less. :D

However, if I was wiring that system, I would attach the wiper of the 10K pots to the input of the LM386 audio amps. Connect the "top" of all the 10K pots to the output of the MP3 so you have a constant load on that gadget. Then use the pots to equalize each channel.
 

newplumber

Senior Member
texas said:
However, if I was wiring that system, I would attach the wiper of the 10K pots to the input of the LM386 audio amps
I think i understand what you are saying but I was arguing with myself about trying to kill noise when mp3 is not playing..so that is why I designed it with the input
of lm386 to always hold to ground ...I will test using a 5k pot or even a 1k pot ...if it becomes a issue I could just kill/open the 12v power with a relay
I also thought of using a extra lm386 close to the mp3 and use that to feed all the others (lm386s)....it will be fun seeing how much "noise" it can make
 

hippy

Technical Support
Staff member
Your volume pot wiring is wrong, should be how Texsaclodhopper describes it.

Otherwise, when you turn the volume down, you will be shorting the MP3 output to 0V and that could well destroy the module.
 

newplumber

Senior Member
hippy said:
Your volume pot wiring is wrong, should be how Texsaclodhopper describes it.

Otherwise, when you turn the volume down, you will be shorting the MP3 output to 0V and that could well destroy the module.
Yes true thanks Hippy/Texas...I was following one of the 1000 schematics on google...I forgot to include the 10uF electrolytic capacitor in front of each pot
so I will change it to how you/texas suggested ....good catch...I didn't even think of what happens when pot is turned down.
 
Last edited:

newplumber

Senior Member
Hi
I was just messing around with the RTC 3231 and MP3
with sound files I downloaded from using the text to speech site
http://www.text2speech.org/
I used the womans voice in slow speed
and then changed the speed and echo in "audacity" (you can change almost everything in that program)
sounds pretty cool on how the device tells the time every minute
Here is my test code ....of course thanks to Marks code for the RTC

Code:
[color=Green]'This program uses a rtc and mp3 to sound out time every minute [/color]
[color=Navy]#picaxe [/color][color=Black]20m2 [/color]
[color=Navy]#NO_DATA
#terminal 4800 [/color]
[color=Blue]SETFREQ M4
let [/color][color=Purple]dirsB [/color][color=DarkCyan]= [/color][color=Navy]%10001000[/color]
[color=Blue]Symbol BAUD_FREQ [/color][color=DarkCyan]= [/color][color=Blue]M8
Symbol BAUD [/color][color=DarkCyan]= [/color][color=Blue]T9600_8
Symbol TX [/color][color=DarkCyan]= [/color][color=Blue]B.3 [/color][color=Green]' --->  to MP3 pin RX 

 [/color][color=Blue]SYMBOL [/color][color=Purple]index    [/color][color=DarkCyan]= [/color][color=Purple]b0     
 [/color][color=Blue]SYMBOL [/color][color=Purple]hours    [/color][color=DarkCyan]= [/color][color=Purple]b1
 [/color][color=Blue]SYMBOL [/color][color=Purple]mins     [/color][color=DarkCyan]= [/color][color=Purple]b2
 [/color][color=Blue]SYMBOL [/color][color=Purple]secs     [/color][color=DarkCyan]= [/color][color=Purple]b3  
 [/color][color=Blue]SYMBOL [/color][color=Purple]day      [/color][color=DarkCyan]= [/color][color=Purple]b7     [/color][color=Green]' not used 
 [/color][color=Blue]SYMBOL [/color][color=Purple]date     [/color][color=DarkCyan]= [/color][color=Purple]b4  
 [/color][color=Blue]SYMBOL [/color][color=Purple]month    [/color][color=DarkCyan]= [/color][color=Purple]b5   
 [/color][color=Blue]SYMBOL [/color][color=Purple]year     [/color][color=DarkCyan]= [/color][color=Purple]b6 
 [/color][color=Blue]SYMBOL [/color][color=Purple]CommonYear  [/color][color=DarkCyan]= [/color][color=Purple]b8
 [/color][color=Blue]SYMBOL [/color][color=Purple]DayNumber   [/color][color=DarkCyan]= [/color][color=Purple]W6 
 [/color][color=Blue]SYMBOL [/color][color=Purple]DSTstart    [/color][color=DarkCyan]= [/color][color=Purple]W7
 [/color][color=Blue]SYMBOL [/color][color=Purple]DSTend      [/color][color=DarkCyan]= [/color][color=Purple]W8  [/color][color=Black]: [/color][color=Blue]SYMBOL [/color][color=Purple]DayS [/color][color=DarkCyan]= [/color][color=Purple]W8[/color]
[color=Blue]Symbol [/color][color=Purple]cmd          [/color][color=DarkCyan]= [/color][color=Purple]b19[/color]
[color=Blue]Symbol [/color][color=Purple]arg          [/color][color=DarkCyan]= [/color][color=Purple]w10 [/color][color=Green]; b21:b20[/color]
[color=Blue]Symbol [/color][color=Purple]arg[/color][color=Black].lsb      [/color][color=DarkCyan]= [/color][color=Purple]b20[/color]
[color=Blue]Symbol [/color][color=Purple]arg[/color][color=Black].msb      [/color][color=DarkCyan]= [/color][color=Purple]b21[/color]
[color=Blue]Symbol [/color][color=Purple]varA         [/color][color=DarkCyan]= [/color][color=Purple]w11

 [/color][color=Black]InitialiseMP3:
  [/color][color=Blue]High TX [/color][color=Green]; set TX pin high for idle high serial
   [/color][color=Blue]Pause [/color][color=Navy]200
  [/color][color=Purple]cmd [/color][color=DarkCyan]= [/color][color=Navy]$09 [/color][color=Black]: [/color][color=Purple]arg [/color][color=DarkCyan]= [/color][color=Navy]$0002 [/color][color=Black]: [/color][color=Blue]Gosub [/color][color=Black]Send [/color][color=Green]' $0002 = SD card 
   [/color][color=Blue]Pause [/color][color=Navy]2000
  [/color][color=Purple]cmd [/color][color=DarkCyan]= [/color][color=Navy]$06 [/color][color=Black]: [/color][color=Purple]arg [/color][color=DarkCyan]= [/color][color=Navy]25    [/color][color=Black]: [/color][color=Blue]Gosub [/color][color=Black]Send [/color][color=Green]' <-- Volume 0 to 30 
   [/color][color=Blue]Pause [/color][color=Navy]100 [/color]

 InitialiseTimeRTC:
    'HI2Csetup I2Cmaster, %11010000, I2Cslow_32, I2Cbyte  ' Set  DS1307 to 100kbps 
      'HI2Cout $0 , ( $00, $32, $08,day, $07 , $04 , $18) ' program DS1307 with GMT
	
 Main: '======== Main Program =================================
 pause 500 
    HI2Csetup I2Cmaster, %11010000, I2Cslow_32, I2Cbyte  ' Set  DS1307 to 100kbps 
      HI2Cin  $0 , (secs,mins,hours,day,date,month,year) ' Read DS1307

	
        FOR bptr = 1 TO 6                     '((((Thanks for Marks RTC code start --->
          @bptr = @bptr/$10*250+@bptr                     ' Convert BCD to Decimal  
        NEXT
If secs => 5 and secs =< 7 then :secs = 6 : endif 		  
 EasternDaylightTime:                       ' United States       
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238              ' First SunDay in November 	   
	IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
	IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
	IF DayNumber = DSTend   AND hours >1 THEN Display    ' DST ends at 0200
	   IF hours =23 THEN : INC date  
	     IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	   ENDIF : hours =hours +1//24           
	  Sertxd ("EDT  ") :  GOTO DateTime                 ' DST +1	  
Display:Sertxd ("EST  ")                                   ' StandardTime  
DateTime:
	  sertxd ("20",#year,"/",#month,"/",#date,"    ")    ' Date 20yy/mm/dd 
         index = mins/10 :mins = mins//10                  
          sertxd (#hours,".",#index,#mins)                 ' 24hr time hh/mm/ss 
	                               '<--- Forum member Marks code end ))) 
if secs = 6 then gosub Sound_out_time ' sound time every minute 
Goto Main 

Sound_out_time:
  cmd = $03 : arg = 15 : Gosub Send 'sound "at the time,the time will be"  from mp3 sd card
  Pause 3500
  
lookup hours,(0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out hours digits of time 12hr mode from mp3 sd card 
  Pause 1500 
lookup index,(0014,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out minute 10s digit of time (0014 = OH)from mp3 sd card 
  Pause 1500   
lookup mins,(0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out minute 1s digit of time from mp3 sd card
  Pause 1500 
Return  
  
Send:
 SetFreq BAUD_FREQ
 Pause 10
 SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
 SetFreq MDEFAULT
Return
Now I just have to add a few more sound files and the display and I've got the best clock in the house
of course I wont use the 20m2....because the 20X2 seems so much easier/faster

btw first part of code is color and the other part is black because it took up too much words (10000 max)
but first time I used PE6's select all ......forum ....which is pretty cool
 
Last edited:

techElder

Well-known member
Keep at it until it works the way you do! :D

I'm curious about this part of your code that sounds out the time. Can you explain the LOOKUP further?

Code:
lookup hours,(0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out hours digits of time 12hr mode from mp3 sd card 
  Pause 1500 
lookup index,(0014,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out minute 10s digit of time (0014 = OH)from mp3 sd card 
  Pause 1500   
lookup mins,(0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out minute 1s digit of time from mp3 sd card
 

hippy

Technical Support
Staff member
Code:
If secs => 5 and secs =< 7 then :secs = 6 : endif 		  
 
if secs = 6 then gosub Sound_out_time ' sound time every minute
I am not entirely sure how that's working. That 'secs' would be expected to cycle between 0 and 59. I would have thought it easier just to use "If secs = 0 Then" which would be the case whenever a new minute started.

Not that I expect you will want a clock speaking the time every minute unless you were looking for some sort of 'psychologically unhinged' defence in court some time :)

If adding a button so it can speak the time there's a case for giving the colloquial time rather than the exact time. For example, instead of "it is thirteen-fourteen" you could have "it is coming up to a quarter past one", instead of "two-thirty-one", "just gone half past two", or whatever those would be your side of the pond.
 

newplumber

Senior Member
Can you explain the LOOKUP further?
I can't explain my unexplained code ...but I will try

in the sd card files are(must be) in number only (ex... 0001.mp3,0002.mp3) ...for the way I have the mp3 set
so in 0000.mp3 is the sound of "zero"
0001.mp3 is the sound of "one"
but when a person selects
Code:
 cmd = $03 : arg = 0000: Gosub Send
the mp3 player ignores 0000 I dont know why
so
Code:
 cmd = $03 : arg = 0001: Gosub Send
is actually playing 0000.mp3 on the sd card
and after 0012.mp3 (which is "twelve")
a person has to remember what mp3 sound number is for none number sounds like 0025.mp3 is ? a person can forget like me :)
in hours I have the rtc hour format in 24 so I just use lookup 1-12 1-12
I probably explained everything that didn't need explaining in the worst horribliest way but its the thought that counts :)



hippy said:
I am not entirely sure how that's working. That 'secs' would be expected to cycle between 0 and 59. I would have thought it easier just to use "If secs = 0 Then" which would be the case whenever a new minute started.

Not that I expect you will want a clock speaking the time every minute unless you were looking for some sort of 'psychologically unhinged' defence in court some time :)
yes lol true it does get annoying but its on low volume so for a test it isn't so bad
and I selected
Code:
If secs => 5 and secs =< 7 then :secs = 6 : endif
because when I had a longer pause ...it wouldn't hit always right on secs number ex. 1,2,3,4,6,7,8
 

techElder

Well-known member
LOOKUP offset,(data0,data1...dataN),variable

Offset - is a variable/constant which specifies which data# (0-N) to place in Variable.
I think the explanation is in the definition of LOOKUP. It does start with zero, but your code starts with the file number for "0001" where it should have "0000" even if "0000" is a dummy placeholder. Then LOOKUP 1 will find the next file number which should be "0001". If the "offset" is more than the list of file numbers, then "varA" doesn't change.

So, it seems from your code that when the "hours" represents "1" then your sound card will play file number "0002", and so on. Now, you may have corrected that by recording "ONE" in file number "0002", but ...
 

newplumber

Senior Member
okay so
my files saved as mp3 files are
Code:
0000.mp3 = "zero"
0001.mp3 = "one"
0002.mp3 = "two" 

what the mp3 code plays is 
0000 =  no sound
0001 = "zero"
0002 = "one"
0003 = "two"
Back to recording voice ...I am going to have my kids record words ...gives it more value
and ...i don't want the whole house taking depression medication so I will just use it at certain times of the day
like 7 am = good morning
12 noon = its lunch time etc
 

techElder

Well-known member
Code:
what the mp3 code plays is 
0000 =  no sound
0001 = "zero"
0002 = "one"
0003 = "two"
I guess I miss the logic in this, but your paying for it! :D :D :D
 

hippy

Technical Support
Staff member
I selected
Code:
If secs => 5 and secs =< 7 then :secs = 6 : endif
because when I had a longer pause ...it wouldn't hit always right on secs number ex. 1,2,3,4,6,7,8
Seems odd that you should be missing anything with time only changing every second which is an eternity for even a slow PICAXE.

I do note you are using "I2Cslow_32" when you are actually running at 4MHz. Not sure what problems that might cause if any.

This is perhaps one of the problems of just throwing code together and not designing from first principles, giving it a modular structure. There is a lot of code being executed which doesn't need to be executed all the time. I would put the RTC reading code in a subroutine which only returned every new minute. Untested but something like ...

Code:
#Define BcdToDec(bcd) bcd / $10 * 250 + bcd

WaitForMinuteTick:
  HI2cSetup I2CMASTER, %11010000, I2CSLOW, I2CBYTE
  Do
    Pause 100
    HI2cIn  $0, (secs,mins,hours,day,date,month,year)
  Loop Until secs = $00
  mins  = BcdToDec( mins  )
  hours = BcdToDec( hours )
  date  = BcdToDec( date  )
  month = BcdToDec( month )
  year  = BcdToDec( year  )
  Gosub FixDst
  Return
 

newplumber

Senior Member
lol I did learn something tho .....incase i had a office where i wanted to be alone .....I could hit the "make poeple leave button"
and have the time call out every 1/2 minute


hippy said:
Seems odd that you should be missing anything with time only changing every second which is an eternity for even a slow PICAXE.
Hippy its my mistake ..when i had a pause longer in the code like
Code:
Main:
pause 950 

and i changed it to 

Main:
pause 500
and your right don't need to read the rtc I will keep working on it
thanks
 
Last edited:

newplumber

Senior Member
Okay here is a better code thanks to hippy's example

Code:
#picaxe 20m2 
#NO_DATA
#terminal 4800 
SETFREQ M4
let dirsB = %10001000
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol TX = B.3 ' --->  to MP3 pin RX 
'RTC  =  SDA  to  picaxe B.5
'RTC  =  SCL  to  picaxe B.7
 SYMBOL index    = b0     
 SYMBOL hours    = b1
 SYMBOL mins     = b2
 SYMBOL secs     = b3  
 SYMBOL day      = b7     ' not used 
 SYMBOL date     = b4  
 SYMBOL month    = b5   
 SYMBOL year     = b6 
 SYMBOL CommonYear  = b8
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = W7
 SYMBOL DSTend      = W8  : SYMBOL DayS = W8
Symbol cmd          = b19
Symbol arg          = w10 ; b21:b20
Symbol arg.lsb      = b20
Symbol arg.msb      = b21
Symbol varA         = w11
Code:
#Define BcdToDec(bcd) bcd / $10 * 250 + bcd

 InitialiseMP3:
  High TX ; set TX pin high for idle high serial
   Pause 200
  cmd = $09 : arg = $0002 : Gosub Send ' $0002 = SD card 
   Pause 2000
  cmd = $06 : arg = 25    : Gosub Send ' <-- Volume 0 to 30 
   Pause 100 

Main:
  Do
    Gosub WaitForMinuteTick
    Gosub Sound_out_time
  Loop   
   
WaitForMinuteTick:
  HI2cSetup I2CMASTER, %11010000, I2CSLOW, I2CBYTE
  Do
    Pause 100
    HI2cIn  $0, (secs,mins,hours,day,date,month,year)
  Loop Until secs = $00
  mins  = BcdToDec( mins  )
  hours = BcdToDec( hours )
  date  = BcdToDec( date  )
  month = BcdToDec( month )
  year  = BcdToDec( year  )
  Gosub EastDaylightTime
Return
  
EastDaylightTime:                       'Code from Marks    for United States        
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238              ' First SunDay in November 	   
	IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
	IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
	IF DayNumber = DSTend   AND hours >1 THEN Display    ' DST ends at 0200
	   IF hours =23 THEN : INC date  
	     IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	   ENDIF : hours =hours +1//24           
	  Sertxd ("EDT  ") :  GOTO DateTime                 ' DST +1	  
Display:Sertxd ("EST  ")                                   ' StandardTime  
DateTime:
	  sertxd ("20",#year,"/",#month,"/",#date,"    ")    ' Date 20yy/mm/dd 
         index = mins/10 :mins = mins//10                  
          sertxd (#hours,".",#index,#mins)                 ' 24hr time hh/mm/ss 
Return 

Sound_out_time:
  cmd = $03 : arg = 15 : Gosub Send 'sound "at the time,the time will be"  from mp3 sd card
  Pause 3500
 

[color=Blue]lookup [/color][color=Black]hours,[/color][color=Blue]([/color][color=Navy]0013[/color][color=Black],[/color][color=Navy]0002[/color][color=Black],[/color][color=Navy]0003[/color][color=Black],[/color][color=Navy]0004[/color][color=Black],[/color][color=Navy]0005[/color][color=Black],[/color][color=Navy]0006[/color][color=Black],[/color][color=Navy]0007[/color][color=Black],[/color][color=Navy]0008[/color][color=Black],[/color][color=Navy]0009[/color][color=Black],[/color][color=Navy]0010[/color][color=Black],[/color][color=Navy]0011[/color][color=Black],[/color][color=Navy]0012[/color][color=Black],[/color][color=Navy]0013[/color][color=Black],[/color][color=Navy]0002[/color][color=Black],[/color][color=Navy]0003[/color][color=Black],[/color][color=Navy]0004[/color][color=Black],[/color][color=Navy]0005[/color][color=Black],[/color][color=Navy]0006[/color][color=Black],[/color][color=Navy]0007[/color][color=Black],[/color][color=Navy]0008[/color][color=Black],[/color][color=Navy]0009[/color][color=Black],[/color][color=Navy]0010[/color][color=Black],[/color][color=Navy]0011[/color][color=Black],[/color][color=Navy]0012[/color][color=Blue])[/color][color=Black],varA 
               [/color][color=Green]'12    1    2    3    4    5    6    7    8    9   10   11   12    1    2    3    4    5    6    7    8    9   10   11 = word sound
                '0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23 = hour value[/color]

   cmd = $03 : arg = varA : Gosub Send 'sound out hours digits of time 12hr mode from mp3 sd card 
  Pause 1500 
lookup index,(0014,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out minute 10s digit of time (0014 = OH)from mp3 sd card 
  Pause 1500   
lookup mins,(0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013),varA   
   cmd = $03 : arg = varA : Gosub Send 'sound out minute 1s digit of time from mp3 sd card
  Pause 1500 
Return  
  
Send:
 SetFreq BAUD_FREQ
 Pause 10
 SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
 SetFreq MDEFAULT
Return
It calls out the time at the top of every minute
Now the big challenge is to add the display code (of course with different times of sound) when I get back home
all in the awesome 20X2
 
Last edited:

hippy

Technical Support
Staff member
I was thinking a main loop something like this, with the individual functions moved to subroutines ...

Code:
Main:
  Gosub InitialiseMP3
  Do
    Gosub WaitForMinuteTick
    Gosub Sound_out_time
  Loop
At the moment you don't have a main loop. The RETURN after the WaitForMinuteTick routine is probably restarting the PICAXE giving the appearance of a loop.
 

newplumber

Senior Member
hippy said:
At the moment you don't have a main loop. The RETURN after the WaitForMinuteTick routine is probably restarting the PICAXE giving the appearance of a loop.
I changed the code in post #106 added loop now
lol funny it was working fine....as always my mistake
but your code example =
Code:
Main:
  Gosub InitialiseMP3
  Do
    Gosub WaitForMinuteTick
    Gosub Sound_out_time
  Loop

 InitialiseMP3:
  High TX ; set TX pin high for idle high serial
   Pause 200
  cmd = $09 : arg = $0002 : Gosub Send ' $0002 = SD card 
   Pause 2000
  cmd = $06 : arg = 25    : Gosub Send ' <-- Volume 0 to 30 
   Pause 100 
Return
wouldn't it be the same as the code I used =
maybe it would make it more clearer if I used gosub InitialiseMP3
Code:
 InitialiseMP3:
  High TX ; set TX pin high for idle high serial
   Pause 200
  cmd = $09 : arg = $0002 : Gosub Send ' $0002 = SD card 
   Pause 2000
  cmd = $06 : arg = 25    : Gosub Send ' <-- Volume 0 to 30 
   Pause 100 
Main:
  Do
    Gosub WaitForMinuteTick
    Gosub Sound_out_time
  Loop
 

newplumber

Senior Member
After playing around with the code here is version B
Code:
' Program uses RTC and MP3 player to sound out time every minute test R1
#picaxe 20m2 
#NO_DATA
#terminal 4800 
SETFREQ M4
let dirsB = %10001000
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol TX = B.3 ' --->  to MP3 pin RX 
'RTC  =  SDA  to  picaxe B.5
'RTC  =  SCL  to  picaxe B.7
 SYMBOL index    = b0     
 SYMBOL hours    = b1
 SYMBOL mins     = b2
 SYMBOL secs     = b3  
 SYMBOL day      = b7     ' not used 
 SYMBOL date     = b4  
 SYMBOL month    = b5   
 SYMBOL year     = b6 
 SYMBOL CommonYear  = b8
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = W7
 SYMBOL DSTend      = W8  : SYMBOL DayS = W8
Symbol cmd          = b19
Symbol arg          = w10 ; b21:b20
Symbol arg.lsb      = b20
Symbol arg.msb      = b21
Symbol varA         = w11

#Define BcdToDec(bcd) bcd / $10 * 250 + bcd

#Macro Send_mp3  
{ SetFreq BAUD_FREQ
 Pause 10
 SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
 SetFreq MDEFAULT
#EndMacro}
#Macro Initmp3 
{High TX ; set TX pin high for idle high serial
Pause 200
cmd = $09
arg = $0002 Send_mp3
Pause 2000
cmd = $06
arg = 25    Send_mp3
Pause 100
#EndMacro}
#Macro Sound_PM 'sound out "PM" from mp3 #0017
{ cmd = $03 
 arg = 0017  Send_mp3 
 Pause 1500
#EndMacro}
#Macro Sound_AM 'sound out "AM" from mp3 #0016
{ cmd = $03 
 arg = 0016  Send_mp3 
 Pause 1500
#EndMacro}
#Macro Sound_Greeting 'sound out "At the time,the time will be" from mp3 #0015
{cmd = $03
arg = 15 Send_mp3
pause 3500
#EndMacro}
#Macro Sound_hour_or_minute
{   cmd = $03 
    arg = varA  Send_mp3 'sound out minute 10s digit of time (0014 = OH)from mp3 sd card 
    Pause 1500 
#EndMacro}

'==========SET TIME on RTC==============
   ' HI2Csetup I2Cmaster, %11010000, I2CSLOW, I2Cbyte  ' Set  DS1307 to 100kbps 
      'HI2Cout $0 , ( $30, $09, $17,day, $09 , $04 , $18) ' program DS1307 with GMT 

Power_Reset:
Initmp3
Main: '===================Main Program================================
 Gosub WaitForMinuteTick
 Gosub Sound_out_time
Goto Main

WaitForMinuteTick:
 { HI2cSetup I2CMASTER, %11010000, I2CSLOW, I2CBYTE
  Do
    Pause 100
    HI2cIn  $0, (secs,mins,hours,day,date,month,year)
  Loop Until secs = $00
  mins  = BcdToDec( mins  )
  hours = BcdToDec( hours )
  date  = BcdToDec( date  )
  month = BcdToDec( month )
  year  = BcdToDec( year  )
  Gosub EastDaylightTime}
Return
EastDaylightTime:                       'Code from Marks    for United States        
    { CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238              ' First SunDay in November 	   
	IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
	IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
	IF DayNumber = DSTend   AND hours >1 THEN Display    ' DST ends at 0200
	   IF hours =23 THEN : INC date  
	     IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	   ENDIF : hours =hours +1//24           
	  Sertxd ("EDT  ") :  GOTO DateTime                 ' DST +1	  
Display:Sertxd ("EST  ")                                   ' StandardTime  
DateTime:
	  sertxd ("20",#year,"/",#month,"/",#date,"    ")    ' Date 20yy/mm/dd 
         index = mins/10 :mins = mins//10                  
          sertxd (#hours,".",#index,#mins)                 ' 24hr time hh/mm/ss 
}
Return

[color=Black]Sound_out_time: [/color][color=Green]'sound out " Thetimewillbe,hour,minute,minute,pm or am "[/color]
[color=Black]Sound_Greeting[/color]
[color=Gray]{[/color][color=Blue]lookup [/color][color=Purple]hours[/color][color=Black],[/color][color=Blue]([/color][color=Navy]0013[/color][color=Black],[/color][color=Navy]0002[/color][color=Black],[/color][color=Navy]0003[/color][color=Black],[/color][color=Navy]0004[/color][color=Black],[/color][color=Navy]0005[/color][color=Black],[/color][color=Navy]0006[/color][color=Black],[/color][color=Navy]0007[/color][color=Black],[/color][color=Navy]0008[/color][color=Black],[/color][color=Navy]0009[/color][color=Black],[/color][color=Navy]0010[/color][color=Black],[/color][color=Navy]0011[/color][color=Black],[/color][color=Navy]0012[/color][color=Black],[/color][color=Navy]0013[/color][color=Black],[/color][color=Navy]0002[/color][color=Black],[/color][color=Navy]0003[/color][color=Black],[/color][color=Navy]0004[/color][color=Black],[/color][color=Navy]0005[/color][color=Black],[/color][color=Navy]0006[/color][color=Black],[/color][color=Navy]0007[/color][color=Black],[/color][color=Navy]0008[/color][color=Black],[/color][color=Navy]0009[/color][color=Black],[/color][color=Navy]0010[/color][color=Black],[/color][color=Navy]0011[/color][color=Black],[/color][color=Navy]0012[/color][color=Blue])[/color][color=Black],[/color][color=Purple]varA 
                [/color][color=Green]'12    1    2    3    4    5    6    7    8    9   10   11   12    1    2    3    4    5    6    7    8    9   10   11 = word sound
                 '0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23 = hour value[/color]
[color=Black]Sound_hour_or_minute[/color]
[color=Blue]lookup [/color][color=Purple]index[/color][color=Black],[/color][color=Blue]([/color][color=Navy]0014[/color][color=Black],[/color][color=Navy]0002[/color][color=Black],[/color][color=Navy]0003[/color][color=Black],[/color][color=Navy]0004[/color][color=Black],[/color][color=Navy]0005[/color][color=Black],[/color][color=Navy]0006[/color][color=Black],[/color][color=Navy]0007[/color][color=Black],[/color][color=Navy]0008[/color][color=Black],[/color][color=Navy]0009[/color][color=Black],[/color][color=Navy]0010[/color][color=Black],[/color][color=Navy]0011[/color][color=Black],[/color][color=Navy]0012[/color][color=Black],[/color][color=Navy]0013[/color][color=Blue])[/color][color=Black],[/color][color=Purple]varA   [/color]
[color=Black]Sound_hour_or_minute  [/color]
[color=Blue]lookup [/color][color=Purple]mins[/color][color=Black],[/color][color=Blue]([/color][color=Navy]0001[/color][color=Black],[/color][color=Navy]0002[/color][color=Black],[/color][color=Navy]0003[/color][color=Black],[/color][color=Navy]0004[/color][color=Black],[/color][color=Navy]0005[/color][color=Black],[/color][color=Navy]0006[/color][color=Black],[/color][color=Navy]0007[/color][color=Black],[/color][color=Navy]0008[/color][color=Black],[/color][color=Navy]0009[/color][color=Black],[/color][color=Navy]0010[/color][color=Black],[/color][color=Navy]0011[/color][color=Black],[/color][color=Navy]0012[/color][color=Black],[/color][color=Navy]0013[/color][color=Blue])[/color][color=Black],[/color][color=Purple]varA   [/color]
[color=Black]Sound_hour_or_minute[/color]
[color=Blue]If [/color][color=Purple]hours [/color][color=DarkCyan]=< [/color][color=Navy]11 [/color][color=Blue]then [/color][color=Black]Sound_AM [/color][color=Blue]endif
If [/color][color=Purple]hours [/color][color=DarkCyan]=> [/color][color=Navy]12 [/color][color=Blue]then [/color][color=Black]Sound_PM [/color][color=Blue]endif [/color][color=Gray]}[/color]
[color=Blue]Return [/color]
it seems to work with my macros ...I need alot more practice tho
 
Last edited:

hippy

Technical Support
Staff member
it seems to work with my macros
Though you don't seem to have invoked you 'Initmp3' macro anywhere within that code.

Your MP3 player is probably initialised now from running an earlier program, which is why it is still working, but you are likely to have problems once you power cycle your hardware.
 

newplumber

Senior Member
hippy said:
Though you don't seem to have invoked you 'Initmp3' macro anywhere within that code.
Your MP3 player is probably initialised now from running an earlier program, which is why it is still working, but you are likely to have problems once you power cycle your hardware.
well simple minds (like me) make simple mistakes :) I personally went over the code like 2+14= 300 times
and again missed the "Initmp3" ...but good reason why it (code) is working and thanks

btw I am slooooooowly bringing macros to life
I am testing your example here
Code:
[color=Blue]Symbol [/color][color=Black]char  [/color][color=DarkCyan]= [/color][color=Purple]b0[/color]
[color=Blue]Symbol [/color][color=Black]match [/color][color=DarkCyan]= [/color][color=Purple]b1[/color]
[color=Gray]{[/color]
[color=Navy]#Define [/color][color=Black]Matched[/color][color=Blue]([/color][color=Black]n,chars[/color][color=Blue]) [/color][color=Purple]b0[/color][color=DarkCyan]=[/color][color=Navy]0 [/color][color=Blue]Then                [/color][color=Black]_
                         [/color][color=Blue]End If                   [/color][color=Black]_
                         match [/color][color=DarkCyan]= [/color][color=Navy]$FF              [/color][color=Black]_
                         [/color][color=Blue]LookDown [/color][color=Black]n,[/color][color=Blue]([/color][color=Black]chars[/color][color=Blue])[/color][color=Black],match _
                         [/color][color=Blue]If [/color][color=Black]match [/color][color=DarkCyan]< [/color][color=Navy]$FF
}[/color]
[color=Blue]Do
  For [/color][color=Black]char [/color][color=DarkCyan]= [/color][color=Red]"a" [/color][color=Blue]To [/color][color=Red]"z"
    [/color][color=Blue]If [/color][color=Black]Matched[/color][color=Blue]([/color][color=Black]char,[/color][color=Red]"aeiou"[/color][color=Blue]) Then
      SerTxd( [/color][color=Red][PLAIN]"["[/PLAIN][/color][color=Black], char, [/color][color=Red][PLAIN]"]"[/PLAIN] [/color][color=Blue])
    Else
      SerTxd( [/color][color=Black]char [/color][color=Blue])
    End If
  Next
  SerTxd( CR[/color][color=Black], [/color][color=Blue]LF )
  Pause [/color][color=Navy]1000[/color]
[color=Blue]Loop[/color]
I still am in the clouds but I see the ground below
 

techElder

Well-known member
I didn't want to sit here and criticize your code, ... but I must. :D

The braces "{" and "}" block your code in the Program Editor (PE) allowing one to hide some code to make it visually easier to read/work on the program. I hope that's why you are using them. They have no significance in a MACRO.

Code:
#Define Matched(n,chars) b0=0 Then                _
                         End If                   _
                         match = $FF              _
                         LookDown n,(chars),match _
                         If match < $FF
Is not a complete MACRO. There is not #ENDMACRO for one, but the IF at the end is as mysterious as the END IF in the middle!
 

newplumber

Senior Member
Yes I should have posted a comment in the original post by Hippy (my mistake #1. E115 )
the "{" and "}" are another genius tool in PE6 especially the option to open/close right next to it

and thanks for trying to help texas .

FWIW I love the the "copy"..."forum"...from PE6 ....just wasn't expecting
the code to blow up in the forum box the first time I pasted :)
with all the [color][flavors][temperatures]
but it keeps everything in line and works awesome
 

newplumber

Senior Member
Hi
I am trying to make my display clock show time but I ran into a problem
Hi2C scl and HSPI sck are on the same pin
The only way I can think of (if possible) is connecting both (apa102 leds , DS3231) to a picaxe 20X2 is to
bit-bang the clock because I need the spi speed for the leds
and the clock speed isn't very important since the display updates every minute
Is there a better way?
 

hippy

Technical Support
Staff member
Is there a better way?
It might be possible to get the serial EUSART operating in synchronous mode to act as a hardware SPI output. You would have to check for pin conflicts and figure out the code for that. That will mean a dig into the Microchip datasheets.

Otherwise I2C or SPI will have to be bit-banged unless one were to add some hardware gating to prevent one from being interfered with by the other and that's probably not worth it.

As to which to bit-bang; bit-banging SPI is easiest, but I2C isn't really that hard and there are example code routines for doing that. It probably is better to use hardware SPI for the LED refresh but I don't know how bad or slow it would be doing it bit-banged.

The APA102_Example_6 sample demonstrates bit-banging and that can be optimised further and speeded up with SETFREQ M64. There would only be minimal changes to make your existing APA102 SPI code bit-banged on the same pins. So would be worth trying it.

I would probably be inclined to agree with you; SPI for fastest LED updates, bit-banged I2C for accessing the RTC. Apart from adding the I2C lower-level routines the only change needed would be to replace the HI2CSETUP and HI2CIN commands.
 

newplumber

Senior Member
Hi Hippy yes if I could get I2c to work with bit_banged that would be the best way
I will check for other samples
 

SolidWorksMagi

Senior Member
+1, that Emic2 chip is the best available. There used to be others (Babblebot, Robovoice, Speakjet, etc) but those are long gone. If you want a retro project, you can still find phoneme-based SP0256-AL2 chips. Counterfeit (but apparently working) chips are available from China: https://www.ebay.com/itm/VOICE-SYNTHESIZER-IC-MICROCHIP-DIP-28-SP0256A-AL2/152765807007

But IMO your best bet is to get a pricier legit chip pair with the crystal: https://www.ebay.com/itm/VINTAGE-GI-SPEECH-VOICE-SYNTHESIZER-IC-SP0256A-AL2-CTS256A-AL2-Text-to-Speech/273088524341

That's still quite a project to assemble. The Emic2 costs just a bit more and is better in every way.

Hi,

The SpeakJet chips are still available. Goto SpeakJet.com to find them, or visit R2Pv1.com to find a really neat MCU board with a SpeakJet chip and audio amplifier onboard and you choose which PICAXE or other chip you want for the MCU to control everything.
 

Buzby

Senior Member
I just found this : https://www.ebay.com/itm/VINTAGE-GI-SPEECH-VOICE-SYNTHESIZER-IC-SP0256A-AL2-CTS256A-AL2-Text-to-Speech

These are the two chips I used to build a text-to-speech machine many years ago.

The beauty of it is that it takes serial text in, translates in real time, then speaks the words and phrases. Simple RTS handshaking controls the source, which could be any PICAXE.

While this was a cool project back in the day, I suspect an RPi, or that other thing, probably has a library to do it cheaper than the price of those vintage chips.

Cheers,

Buzby
 
Top