The pgenPreviousMicros variable in pgen() needs to be declared as a static variable, so that it keeps its value between calls. (Otherwise it will be allocated automatically on the stack and the value will be discarded when the function returns.) This change is important because pgen() won't work correctly without it.
static unsigned long pgenPreviousMicros = 0;
Given that your logging is only done once per second, using micros() to time it seems overkill. I would use millis() unless you need the extra resolution of micros(), although what you have ought to work.
The update to previousMicros is in the right code block now. Personally I'd prefer to put it at the top of the block (next to the 'if' statement that is doing your elapsed time check) so that it is more obvious that it is updated correctly, but it won't affect the behaviour.
To eliminate the redundant calls to micros() you would save the value of micros() in a variable somewhere near the start of the function.
unsigned long nowMicros = micros();
Then you would use the currentMicros variable throughout the rest of the function where you had calls to millis(). I wouldn't expect this change to make much difference to the functionality but it just eliminates the possibility of inaccurate timing if the value of millis() changes while this function is running.
I haven't spotted the dataString statement that you asked about.