cheors
Junior Member
Posts: 33
|
Post by cheors on Sept 20, 2019 12:37:00 GMT -6
May be there no difference between the 2 methods. But i prefer the last one by precaution.
|
|
|
Post by creasysee on Sept 20, 2019 13:57:26 GMT -6
Hi all! 1. Calculations - 20 ms need to move the impulse in one side and back for 50 Hz; - for example 20 channels, this gives 40 switchings per 20 ms. - so aduino should make switch every 20ms/40sw = 0.5ms = 500 us - for 20 channels give us 3 registers, so we need to save 24 bits (3 bytes) in each switching, it gives us 3 shiftOut commands and 2 digitalWrite commands per one step (500 us) - the code of shiftOut has 3 calls of the digitalWrite function in the loop of 8 bits, so we have 3 * 3 * 8 + 2 = 74 calls of the digitalWrite per 500 us. 500us/74calls = 6.7us/call, so the digitalWrite should take not more than 6.7us!!! In some cases, people got time for digitalWrite more than 17us (Arduino 16 MHz)! The Arduino has a lot of interrupts, so your frequency can be unstable and you can not get the frequency 50/60 Hz. So, you shouldn't use the digitalWrite and shiftOut functions. You should use PORTX functions only. 2. Resume. If you have less than 30 channel, don't use registers, use latch buffers only and control it directly. For Arduino 2560 Mega you can use ports PORTA, PORTB, PORTC and PORTL. Total 32 ports: If you have more than 30 channels you should use reversible registers AND DON'T SAVE NOTHING IN LOOP! You need to shift only a digital '1' recorded in the setup function (see my code in the neighboring thread). EDIT: I was getting 5kHz/24channels of output frequency on Arduino 2560 Mega. Regards, creasysee
|
|
|
Post by Marathonman on Sept 20, 2019 15:41:50 GMT -6
Good post Creasysee. i can honestly say i have never heard of reversible registers in my life even with dealing with Aruino. if that is the case i need to look it up unless of course you are talking about shift registers. in both my cases as i am pursuing two different avenues of SPI from two experience Arduino forum members. i am dealing with SPI which can run very fast at half clock speeds if i needed which on a cheap Arduino is at 8 Mhz . SPI doesn't have to deal with interrups which by the way can be shut off. ALL agreed Dwrite and Shout is NOT the way to go. PS; i already have one sketch that compiles but the other needs more work.
MM
|
|
|
Post by Marathonman on Sept 21, 2019 7:58:15 GMT -6
After speaking to two very experienced people on Arduino cc forum with more than 10k + posts both said it does not natter what pins on a port are active with almost any chip as long as the total ma current does not exceed maximum allowable limits of the pin and or the chip.
MM
|
|
|
Post by creasysee on Sept 22, 2019 8:07:12 GMT -6
Thanks, Marathonman. I'm used 74F299 chips. The datasheet (attached) says: "The 74F299 is an 8-bit universal shift/storage register with 3-STATE outputs. Four modes of operation are possible: hold (store), shift left, shift right and load data" Other words, I'm using a load data in a setup function and shift left/shift right in a loop function. Of course, I used digitalWriteFast instead of digitalWrite, but PORTX will be best. Regards, creasysee 74F299.pdf (85.86 KB) EDIT: Remember, I used 2 groups of registers to create an overlap. For one group of registers, the shift (per step) will take 4 commands of digitalWriteFast/PORTX (instead of 74, see my previous post), for two groups of registers 8 commands. The digitalWriteFast command this is part of a digitalWriteFast github.com/NicksonYap/digitalWriteFast library.
|
|
|
Post by Marathonman on Sept 22, 2019 10:44:00 GMT -6
Thats funny as i was looking at the 299 a few days ago and downloaded the data sheet to my computer. if you can get digitalwritefast to switch fast enough then that is good. i personally no not know how fast it is just reg digitalwrite which is sleep time slow. i would post the code i have but i have not tested it yet so i will wait until i do. FYI, it was Paul Stoffregen of PJRC that wrote the macros for the digitalwritefast commands in 2010.
Ps. just so you know the shift command is also slowing things down like digital write does. just so the readers and guests know the speed difference between the the digitalWrtieFast/Read/pinModeFast that Paul wrote runs at 125ns and the regular digitalWrite/Read/pinMode runs at 6280 ns each which can add up to a significant delay especially on large sketches. the reason they are much faster is because Paul rewrote the commands at the macro level that enables direct port manipulation. want a sketch to run faster then use DWF, DRF or PMF it's that simple.
Thank you Creasysee for that great PDF. i have read it before but it makes more sense when programming. PS; it is to bad we can not use the old 556 chip, it has 16 channels all on the lower half of the chip. a trace layout dream come true. unfortunately it only sinks current and a lot of it at that.
happy Figuera'ing,
MM
|
|
|
Post by Marathonman on Sept 23, 2019 20:38:30 GMT -6
I literally can not believe my eyes, i am sitting in front of my computer using the Arduino IDE 1.8.10 the new one and the code i have compiles so fast i can not believe it. it was changed last night to correct a minor pin swap then compiled in less than 7 seconds. Wow that's fast. before i started this whole SPI thing i really did not know what spi function was used for and just how little of code is used to get the proper functions. i literally only have 22 actual lines of code not counting the brackets and spaces plus addition descriptions of actions. i am sure i might need a few more lines but not much.
it only takes up 15% of an Arduino Leonardo's program storage. the bad news is the DigitalWriteFast/pinModeFast is only supported on a few Arduino's and the other one i have is the Tensy 3.6 @ 180 Mhz is NOT one of them. the good news is the Leonardo is cheap on ebay and can run this program like a heavy weight champ on SPI at a top freq of 8Mhz. i do happen to have the IDE running on a very nice but old Gigabyte UD3 with a 3960E proc, 16 gig mem, Kingston SSDs, 580GTX on win 7 & 10 so everything runs fast and looks good on a 45 inch HD TV.
i should be able to at least give a sneak preview over the next week.
MM
|
|
|
Post by Marathonman on Sept 26, 2019 8:12:57 GMT -6
Here is a very good article on DigitlWriteFast by an old school programmer that has sense passed away. pay close attention to the port manipulation he does which i find very interesting. link to Post
MM
|
|
cheors
Junior Member
Posts: 33
|
Post by cheors on Sept 26, 2019 9:20:31 GMT -6
Glad to see that PORTx instruction is the fastest one. Even digitalWriteFast and digitalReadFast (which call the C "BitSet, bitClear" functions) seem to be a little bit slower with my compiler.
|
|
|
Post by Marathonman on Sept 26, 2019 12:18:11 GMT -6
Actually at the speeds we are operating at (50-60 Hz) DigitalWriteFast is plenty fast enough for these programs along with port manipulations but why use it if you do not have to "Right". i am dealing with SPi directly do i do not even have to declare the pins in setup as it already knows the SPI pins. SS well that is another story as any pin can be set up for SS behavior. as per Creasysee's post the (DWF) command is at 125 ns which is actually plenty fast.
This is the real deal here dealing with port commands in either binary, variables or decimal. see below the use of direct port manipulation without DWF and shortening the commands while you are at it.
int on = B00100000;
int off = B00000000;
void setup()
{ DDRB = on;
}
void loop()
{
PORTB = on; //Turn LED on. delay(); // use millis() to test, micros() to run. PORTB = off; //Turn LED off. delay();
MM
|
|
cheors
Junior Member
Posts: 33
|
Post by cheors on Sept 27, 2019 7:10:44 GMT -6
And you could also use assembler. That gives the best timing accuracy and not so difficult. All the PORTX "out" instructions take only one 62.5 nS cycle.
;====================================================================
; Main.asm file Figuera ASMB project ; Created: jeu. sept. 26 2019 CHEORS ; Processor: ATmega328P 13 bits shift register with Arduino Nano 16MHz ; Compiler: AVRASM (Proteus)
;==================================================================== ;====================================================================
; DEFINITIONS
;====================================================================
;====================================================================
; VARIABLES
;====================================================================
;====================================================================
; RESET and INTERRUPT VECTORS
;====================================================================
ldi r19,0b00111111
ldi r29,255
out DDRB,r19 ; DDRB=255 =PORTB = 6 bits Outputs
out DDRD,r29 ; DDRD=255 =PORTD = 8 bits Outputs
ldi r20,0 ; some constants in CPU registers
ldi r21,1 ; bit 0
ldi r22,2 ; bit 1
ldi r23,4 ; bit 2
ldi r24,8
ldi r25,16
ldi r26,32
ldi r27,64
ldi r28,128
rjmp Start
; delay routine
delay_n_ms:
;;; Delay about r18*1ms. Destroys r18, r30, and r31.
;;; One millisecond is about 16000 cycles at 16MHz.
; adjust r18, r30 and r31 for 416us delay_n_ms and 19.995 ms 50Hz total
ldi r18,1 ; delay
GoOn: ldi r31, 6 ; high(6)
ldi r30, 127 ; low(127)
delaylp:
sbiw r30, 1
brne delaylp
subi r18, 1
brne GoOn
ret
; Reset Vector
;====================================================================
; CODE SEGMENT
;====================================================================
Start:
out PORTD,r21 ;PORTD = bit 1
call delay_n_ms
out PORTB,r20 ;PORTB =0
call delay_n_ms
out PORTB,r21 ;PORTB =bit 1
call delay_n_ms
out PORTD,r20 ;PORTD =0
call delay_n_ms
out PORTD,r22 ;PORTD =bit 2
call delay_n_ms
out PORTB,r20 ;PORTB =0
call delay_n_ms
out PORTB,r22 ;PORTB =bit 2
call delay_n_ms
out PORTD,r20 ;PORTD =0
call delay_n_ms;
; And so on then decrement............................
out PORTD,r23 ;PORTD =4
call delay_n_ms
out PORTB,r20 ;PORTB =0
call delay_n_ms
out PORTB,r22 ;PORTB =2
call delay_n_ms
out PORTD,r20 ;PORTD =0
call delay_n_ms
out PORTD,r22 ;PORTD =2
call delay_n_ms
out PORTB,r20 ;PORTB =0
call delay_n_ms
out PORTB,r21 ;PORTB =1
call delay_n_ms
out PORTD,r20 ;PORTD =0
call delay_n_ms ....................................................................................
;Loop:
rjmp Start
|
|
peter
New Member
Posts: 24
|
Post by peter on Sept 27, 2019 8:13:37 GMT -6
For what type of arduino is this little programm??
|
|
|
Post by Marathonman on Sept 27, 2019 10:58:29 GMT -6
Peter; Assembler programming language. Assembly language (also known as ASM) is a programming language for computers and other devices, and it's generally considered a low-level variant when compared to more advanced languages that offer additional functionality. it compiles to binary just like the standard Arduino and C C++ language does. Cheors; So it seems in your code you are using only 13 channels am i correct? it may well be breadboard time, that way the visuals can be observed in action then adjustments made. i have everything i need for testing the code by next week with a huge breadboard coming thanks to a small *donation *(thank you)*. the LED's are a great plus in observing the code actions and i have a pack of 100 LED's to play with. let the fun begin, testing the code will start next weekend after i set the test circuit up on the breadboard. Breadboard that is coming below. MM
|
|
cheors
Junior Member
Posts: 33
|
Post by cheors on Sept 27, 2019 11:21:22 GMT -6
This code is for Arduino Nano but can be adapted for other Arduino boards. Yes, i just started with a 13 bits configuration but Nano can manage up to 20 I/O bits. (PORTB =6 bits,PORTC =6 bits, PORTD =8 bits)
PS : tell CHEORS not Cheros. Thanks _
|
|
|
Post by Marathonman on Sept 27, 2019 20:50:01 GMT -6
Ops !, corrected. now it's breadboard time right ?.. lets make night rider jealous.
i do not have logic level n-channel to play with nor p-channel. the one in my transistor board design has an RDS on @ 2.6 volts so it is fully on at 5 volts which will be just great turning on an p-channel to do the heavy lifting. at least i can test the program and work out any bugs. istill need a few more parts for my 100 volt power supply so i will test with low voltage first which is safer then move to 100.
MM
|
|