diff --git a/src/MNH/ini_aircraft_balloon.f90 b/src/MNH/ini_aircraft_balloon.f90
index a9fb888da7ed8926609defc9fc3cd434e35b5b95..6191e60d53b4158b0e065c67a48f1540720c3126 100644
--- a/src/MNH/ini_aircraft_balloon.f90
+++ b/src/MNH/ini_aircraft_balloon.f90
@@ -6,41 +6,21 @@
 ! Modifications:
 !  P. Wautelet 01/10/2020: bugfix: DEFAULT_FLYER: add missing default values
 !  P. Wautelet    06/2022: reorganize flyers
+!  P. Wautelet 25/08/2022: write balloon positions in netCDF4 files inside HDF5 groups
 !-----------------------------------------------------------------
 
-!      #########################
-MODULE MODI_INI_AIRCRAFT_BALLOON
-!      #########################
-!
-INTERFACE
-!
-      SUBROUTINE INI_AIRCRAFT_BALLOON(TPINIFILE,                    &
-                                      PTSTEP, TPDTSEG, PSEGLEN,     &
-                                      KRR, KSV, KKU, OUSETKE,       &
-                                      PLATOR, PLONOR                )
-!
-USE MODD_IO, ONLY: TFILEDATA
-USE MODD_TYPE_DATE
-!
-TYPE(TFILEDATA),    INTENT(IN) :: TPINIFILE !Initial file
-REAL,               INTENT(IN) :: PTSTEP  ! time step
-TYPE(DATE_TIME),    INTENT(IN) :: TPDTSEG ! segment date and time
-REAL,               INTENT(IN) :: PSEGLEN ! segment length
-INTEGER,            INTENT(IN) :: KRR     ! number of moist variables
-INTEGER,            INTENT(IN) :: KSV     ! number of scalar variables
-INTEGER,            INTENT(IN) :: KKU     ! number of vertical levels 
-LOGICAL,            INTENT(IN) :: OUSETKE ! flag to use tke
-REAL,               INTENT(IN) :: PLATOR  ! latitude of origine point
-REAL,               INTENT(IN) :: PLONOR  ! longitude of origine point
-!
-!-------------------------------------------------------------------------------
-!
-END SUBROUTINE INI_AIRCRAFT_BALLOON
-!
-END INTERFACE
-!
-END MODULE MODI_INI_AIRCRAFT_BALLOON
-!
+!###############################
+MODULE MODE_INI_AIRCRAFT_BALLOON
+!###############################
+
+IMPLICIT NONE
+
+PRIVATE
+
+PUBLIC :: INI_AIRCRAFT_BALLOON
+
+CONTAINS
+
 !     ###############################################################
       SUBROUTINE INI_AIRCRAFT_BALLOON(TPINIFILE,                    &
                                       PTSTEP, TPDTSEG, PSEGLEN,     &
@@ -294,9 +274,19 @@ END SUBROUTINE ALLOCATE_FLYER
 !----------------------------------------------------------------------------
 !----------------------------------------------------------------------------
 SUBROUTINE INI_LAUNCH(KNBR,TPFLYER)
-!
+
+#ifdef MNH_IOCDF4
+USE NETCDF,             ONLY: NF90_INQ_NCID, NF90_NOERR
+#endif
+
+USE MODD_IO,            ONLY: ISP, TFILEDATA
+#ifdef MNH_IOCDF4
+USE MODD_MPIF
+USE MODD_PRECISION,     ONLY: CDFINT, CDFINT_MPI
+#endif
+
 use MODE_IO_FIELD_READ, only: IO_Field_read
-!
+
 INTEGER,             INTENT(IN)    :: KNBR
 CLASS(TBALLOONDATA), INTENT(INOUT) :: TPFLYER
 !
@@ -304,42 +294,36 @@ CLASS(TBALLOONDATA), INTENT(INOUT) :: TPFLYER
 !
 !*      0.2  declaration of local variables
 !
+#ifdef MNH_IOCDF4
+INTEGER              :: IERR
+INTEGER(KIND=CDFINT) :: IGROUPID
+INTEGER(KIND=CDFINT) :: ISTATUS
+INTEGER(KIND=CDFINT), DIMENSION(2) :: IDATA ! Intermediate array to allow merge of 2 MPI broadcasts
+#endif
+LOGICAL :: GREAD ! True if balloon position was read in synchronous file
 REAL :: ZLAT ! latitude of the balloon
 REAL :: ZLON ! longitude of the balloon
-!
-IF (TPFLYER%CMODEL == 'MOB' .AND. TPFLYER%NMODEL /= 0) TPFLYER%NMODEL=1
-IF (TPFLYER%NMODEL > NMODEL) TPFLYER%NMODEL=0
+#ifdef MNH_IOCDF4
+TYPE(TFILEDATA) :: TZFILE
+#endif
+
 IF ( IMI /= TPFLYER%NMODEL ) RETURN
-!
+
+GREAD = .FALSE.
 LFLYER=.TRUE.
-!
-IF (TPFLYER%CTITLE=='          ') THEN
-  WRITE(TPFLYER%CTITLE,FMT='(A6,I2.2)') TPFLYER%CTYPE,KNBR
-END IF
-!
+
 IF ( CPROGRAM == 'MESONH' .OR. CPROGRAM == 'SPAWN ' .OR. CPROGRAM == 'REAL  ' ) THEN
-  ! read the current location in the FM_FILE
-  !
-  TZFIELD = TFIELDMETADATA(                   &
-    CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LAT', &
-    CSTDNAME   = '',                          &
-    CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LAT', &
-    CUNITS     = 'degree',                    &
-    CDIR       = '--',                        &
-    CCOMMENT   = '',                          &
-    NGRID      = 0,                           &
-    NTYPE      = TYPEREAL,                    &
-    NDIMS      = 0,                           &
-    LTIMEDEP   = .TRUE.                       )
-  CALL IO_Field_read(TPINIFILE,TZFIELD,ZLAT,IRESP)
-  !
-  IF ( IRESP /= 0 ) THEN
-    WRITE(ILUOUT,*) "INI_LAUNCH: Initial location take for ",TPFLYER%CTITLE
-  ELSE
+  ! Read the current location in the synchronous file
+
+  IF ( TPINIFILE%CFORMAT == 'LFI'                                                             &
+       .OR. ( TPINIFILE%CFORMAT == 'NETCDF4' .AND.                                            &
+              (        TPINIFILE%NMNHVERSION(1) < 5                                           &
+                .OR. ( TPINIFILE%NMNHVERSION(1) == 5 .AND. TPINIFILE%NMNHVERSION(2) < 6 ) ) ) ) THEN
+    ! Read in LFI file or in old format if netCDF (MesoNH < 5.6)
     TZFIELD = TFIELDMETADATA(                   &
-      CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LON', &
+      CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LAT', &
       CSTDNAME   = '',                          &
-      CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LON', &
+      CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LAT', &
       CUNITS     = 'degree',                    &
       CDIR       = '--',                        &
       CCOMMENT   = '',                          &
@@ -347,65 +331,173 @@ IF ( CPROGRAM == 'MESONH' .OR. CPROGRAM == 'SPAWN ' .OR. CPROGRAM == 'REAL  ' )
       NTYPE      = TYPEREAL,                    &
       NDIMS      = 0,                           &
       LTIMEDEP   = .TRUE.                       )
-    CALL IO_Field_read(TPINIFILE,TZFIELD,ZLON)
-    !
-    TZFIELD = TFIELDMETADATA(                   &
-      CMNHNAME   = TRIM(TPFLYER%CTITLE)//'ALT', &
-      CSTDNAME   = '',                          &
-      CLONGNAME  = TRIM(TPFLYER%CTITLE)//'ALT', &
-      CUNITS     = 'm',                         &
-      CDIR       = '--',                        &
-      CCOMMENT   = '',                          &
-      NGRID      = 0,                           &
-      NTYPE      = TYPEREAL,                    &
-      NDIMS      = 0,                           &
-      LTIMEDEP   = .TRUE.                       )
-    CALL IO_Field_read(TPINIFILE,TZFIELD,TPFLYER%XZ_CUR)
-    !
-    TPFLYER%XP_CUR   = XUNDEF
-    !
-    TZFIELD = TFIELDMETADATA(                       &
-      CMNHNAME   = TRIM(TPFLYER%CTITLE)//'WASCENT', &
-      CSTDNAME   = '',                              &
-      CLONGNAME  = TRIM(TPFLYER%CTITLE)//'WASCENT', &
-      CUNITS     = 'm s-1',                         &
-      CDIR       = '--',                            &
-      CCOMMENT   = '',                              &
-      NGRID      = 0,                               &
-      NTYPE      = TYPEREAL,                        &
-      NDIMS      = 0,                               &
-      LTIMEDEP   = .TRUE.                           )
-    CALL IO_Field_read(TPINIFILE,TZFIELD,TPFLYER%XWASCENT)
-    !
-    TZFIELD = TFIELDMETADATA(                   &
-      CMNHNAME   = TRIM(TPFLYER%CTITLE)//'RHO', &
-      CSTDNAME   = '',                          &
-      CLONGNAME  = TRIM(TPFLYER%CTITLE)//'RHO', &
-      CUNITS     = 'kg m-3',                    &
-      CDIR       = '--',                        &
-      CCOMMENT   = '',                          &
-      NGRID      = 0,                           &
-      NTYPE      = TYPEREAL,                    &
-      NDIMS      = 0,                           &
-      LTIMEDEP   = .TRUE.                       )
-    CALL IO_Field_read(TPINIFILE,TZFIELD,TPFLYER%XRHO)
-    !
+    CALL IO_Field_read(TPINIFILE,TZFIELD,ZLAT,IRESP)
+
+    IF ( IRESP == 0 ) THEN
+      GREAD = .TRUE.
+
+      TZFIELD = TFIELDMETADATA(                   &
+        CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LON', &
+        CSTDNAME   = '',                          &
+        CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LON', &
+        CUNITS     = 'degree',                    &
+        CDIR       = '--',                        &
+        CCOMMENT   = '',                          &
+        NGRID      = 0,                           &
+        NTYPE      = TYPEREAL,                    &
+        NDIMS      = 0,                           &
+        LTIMEDEP   = .TRUE.                       )
+      CALL IO_Field_read(TPINIFILE,TZFIELD,ZLON)
+
+      TZFIELD = TFIELDMETADATA(                   &
+        CMNHNAME   = TRIM(TPFLYER%CTITLE)//'ALT', &
+        CSTDNAME   = '',                          &
+        CLONGNAME  = TRIM(TPFLYER%CTITLE)//'ALT', &
+        CUNITS     = 'm',                         &
+        CDIR       = '--',                        &
+        CCOMMENT   = '',                          &
+        NGRID      = 0,                           &
+        NTYPE      = TYPEREAL,                    &
+        NDIMS      = 0,                           &
+        LTIMEDEP   = .TRUE.                       )
+      CALL IO_Field_read(TPINIFILE,TZFIELD,TPFLYER%XZ_CUR)
+
+      TPFLYER%XP_CUR   = XUNDEF
+
+      TZFIELD = TFIELDMETADATA(                       &
+        CMNHNAME   = TRIM(TPFLYER%CTITLE)//'WASCENT', &
+        CSTDNAME   = '',                              &
+        CLONGNAME  = TRIM(TPFLYER%CTITLE)//'WASCENT', &
+        CUNITS     = 'm s-1',                         &
+        CDIR       = '--',                            &
+        CCOMMENT   = '',                              &
+        NGRID      = 0,                               &
+        NTYPE      = TYPEREAL,                        &
+        NDIMS      = 0,                               &
+        LTIMEDEP   = .TRUE.                           )
+      CALL IO_Field_read(TPINIFILE,TZFIELD,TPFLYER%XWASCENT)
+
+      TZFIELD = TFIELDMETADATA(                   &
+        CMNHNAME   = TRIM(TPFLYER%CTITLE)//'RHO', &
+        CSTDNAME   = '',                          &
+        CLONGNAME  = TRIM(TPFLYER%CTITLE)//'RHO', &
+        CUNITS     = 'kg m-3',                    &
+        CDIR       = '--',                        &
+        CCOMMENT   = '',                          &
+        NGRID      = 0,                           &
+        NTYPE      = TYPEREAL,                    &
+        NDIMS      = 0,                           &
+        LTIMEDEP   = .TRUE.                       )
+      CALL IO_Field_read(TPINIFILE,TZFIELD,TPFLYER%XRHO)
+    END IF
+#ifdef MNH_IOCDF4
+  ELSE
+    ! Read in netCDF file (new structure since MesoNH 5.6)
+    IF ( ISP == TPINIFILE%NMASTER_RANK ) ISTATUS = NF90_INQ_NCID( TPINIFILE%NNCID, TRIM( TPFLYER%CTITLE ), IGROUPID )
+
+    IDATA(:) = [ ISTATUS, IGROUPID ] ! Merge 2 broadcasts into 1
+    CALL MPI_BCAST( IDATA, SIZE( IDATA ), CDFINT_MPI, TPINIFILE%NMASTER_RANK - 1, TPINIFILE%NMPICOMM, IERR )
+    ISTATUS  = IDATA(1)
+    IGROUPID = IDATA(2)
+
+    IF ( ISTATUS == NF90_NOERR ) THEN
+      GREAD = .TRUE.
+
+      TZFILE = TPINIFILE
+      TZFILE%NNCID = IGROUPID
+
+      TZFIELD = TFIELDMETADATA(  &
+        CMNHNAME   = 'LAT',      &
+        CSTDNAME   = '',         &
+        CLONGNAME  = 'LAT',      &
+        CUNITS     = 'degree',   &
+        CDIR       = '--',       &
+        CCOMMENT   = 'latitude', &
+        NGRID      = 0,          &
+        NTYPE      = TYPEREAL,   &
+        NDIMS      = 0,          &
+        LTIMEDEP   = .TRUE.      )
+      CALL IO_Field_read(TZFILE,TZFIELD,ZLAT)
+
+      TZFIELD = TFIELDMETADATA(   &
+        CMNHNAME   = 'LON',       &
+        CSTDNAME   = '',          &
+        CLONGNAME  = 'LON',       &
+        CUNITS     = 'degree',    &
+        CDIR       = '--',        &
+        CCOMMENT   = 'longitude', &
+        NGRID      = 0,           &
+        NTYPE      = TYPEREAL,    &
+        NDIMS      = 0,           &
+        LTIMEDEP   = .TRUE.       )
+      CALL IO_Field_read(TZFILE,TZFIELD,ZLON)
+
+      TZFIELD = TFIELDMETADATA(  &
+        CMNHNAME   = 'ALT',      &
+        CSTDNAME   = '',         &
+        CLONGNAME  = 'ALT',      &
+        CUNITS     = 'm',        &
+        CDIR       = '--',       &
+        CCOMMENT   = 'altitude', &
+        NGRID      = 0,          &
+        NTYPE      = TYPEREAL,   &
+        NDIMS      = 0,          &
+        LTIMEDEP   = .TRUE.      )
+      CALL IO_Field_read(TZFILE,TZFIELD,TPFLYER%XZ_CUR)
+
+      TPFLYER%XP_CUR   = XUNDEF
+
+      TZFIELD = TFIELDMETADATA(               &
+        CMNHNAME   = 'WASCENT',               &
+        CSTDNAME   = '',                      &
+        CLONGNAME  = 'WASCENT',               &
+        CUNITS     = 'm s-1',                 &
+        CDIR       = '--',                    &
+        CCOMMENT   = 'ascent vertical speed', &
+        NGRID      = 0,                       &
+        NTYPE      = TYPEREAL,                &
+        NDIMS      = 0,                       &
+        LTIMEDEP   = .TRUE.                   )
+      CALL IO_Field_read(TZFILE,TZFIELD,TPFLYER%XWASCENT)
+
+      TZFIELD = TFIELDMETADATA(     &
+        CMNHNAME   = 'RHO',         &
+        CSTDNAME   = '',            &
+        CLONGNAME  = 'RHO',         &
+        CUNITS     = 'kg m-3',      &
+        CDIR       = '--',          &
+        CCOMMENT   = 'air density', &
+        NGRID      = 0,             &
+        NTYPE      = TYPEREAL,      &
+        NDIMS      = 0,             &
+        LTIMEDEP   = .TRUE.         )
+      CALL IO_Field_read(TZFILE,TZFIELD,TPFLYER%XRHO)
+    END IF
+#endif
+  END IF
+
+  IF ( GREAD ) THEN
     CALL SM_XYHAT( PLATOR, PLONOR, ZLAT, ZLON, TPFLYER%XX_CUR, TPFLYER%XY_CUR )
+
     TPFLYER%LFLY = .TRUE.
-    WRITE(ILUOUT,*) &
-    "INI_LAUNCH: Current location read in FM file for ",TPFLYER%CTITLE
+
+    CMNHMSG(1) = 'current location read from synchronous file for ' // TRIM( TPFLYER%CTITLE )
     IF (TPFLYER%CTYPE== 'CVBALL') THEN
-      WRITE(ILUOUT,*) &
-       " Lat=",ZLAT," Lon=",ZLON," Alt=",TPFLYER%XZ_CUR," Wasc=",TPFLYER%XWASCENT
+      WRITE( CMNHMSG(2), * ) " Lat=", ZLAT, " Lon=", ZLON
+      WRITE( CMNHMSG(3), * ) " Alt=", TPFLYER%XZ_CUR, " Wasc=", TPFLYER%XWASCENT
     ELSE IF (TPFLYER%CTYPE== 'ISODEN') THEN
-      WRITE(ILUOUT,*) &
-       " Lat=",ZLAT," Lon=",ZLON," Rho=",TPFLYER%XRHO
+      WRITE( CMNHMSG(2), * ) " Lat=", ZLAT, " Lon=", ZLON, " Rho=", TPFLYER%XRHO
     END IF
-    !
+    CALL PRINT_MSG( NVERB_INFO, 'GEN', 'INI_LAUNCH' )
+
     TPFLYER%TFLYER_TIME%XTSTEP  = MAX ( PTSTEP, TPFLYER%TFLYER_TIME%XTSTEP )
+  ELSE
+    ! The position is not found, data is not in the synchronous file
+    ! Use the position given in namelist
+    CALL PRINT_MSG( NVERB_INFO, 'GEN', 'INI_LAUNCH', 'initial location taken from namelist for ' // TRIM( TPFLYER%CTITLE ) )
   END IF
   !
-ELSE IF (CPROGRAM == 'DIAG  ' ) THEN
+ELSE IF ( CPROGRAM == 'DIAG  ' ) THEN
   IF ( LAIRCRAFT_BALLOON ) THEN
     ! read the current location in MODD_DIAG_FLAG
     !
@@ -415,10 +507,9 @@ ELSE IF (CPROGRAM == 'DIAG  ' ) THEN
     IF (TPFLYER%XZ_CUR /= XUNDEF .AND. ZLAT /= XUNDEF .AND. ZLON /= XUNDEF ) THEN
       CALL SM_XYHAT( PLATOR, PLONOR, ZLAT, ZLON, TPFLYER%XX_CUR, TPFLYER%XY_CUR )
       TPFLYER%LFLY = .TRUE.
-      WRITE(ILUOUT,*) &
-      "INI_LAUNCH: Current location read in MODD_DIAG_FLAG for ",TPFLYER%CTITLE
-      WRITE(ILUOUT,*) &
-            " Lat=",ZLAT," Lon=",ZLON," Alt=",TPFLYER%XZ_CUR
+      CMNHMSG(1) = 'current location read from MODD_DIAG_FLAG for ' // TRIM( TPFLYER%CTITLE )
+      WRITE( CMNHMSG(2), * ) " Lat=", ZLAT, " Lon=", ZLON," Alt=",TPFLYER%XZ_CUR
+      CALL PRINT_MSG( NVERB_INFO, 'GEN', 'INI_LAUNCH' )
     END IF
     !
     TPFLYER%TFLYER_TIME%XTSTEP  = MAX (XSTEP_AIRCRAFT_BALLOON , TPFLYER%TFLYER_TIME%XTSTEP )
@@ -488,3 +579,5 @@ END SUBROUTINE INI_FLIGHT
 !----------------------------------------------------------------------------
 !
 END SUBROUTINE INI_AIRCRAFT_BALLOON
+
+END MODULE MODE_INI_AIRCRAFT_BALLOON
diff --git a/src/MNH/ini_modeln.f90 b/src/MNH/ini_modeln.f90
index 5bf5d68bb487e94f6aa064d712cd10c9713c0bab..11dad29e3b7aae197cde18308ab71eaa3e3a58b3 100644
--- a/src/MNH/ini_modeln.f90
+++ b/src/MNH/ini_modeln.f90
@@ -401,6 +401,7 @@ USE MODD_TURB_n
 USE MODD_VAR_ll,            only: IP
 
 USE MODE_GATHER_ll
+USE MODE_INI_AIRCRAFT_BALLOON, only: INI_AIRCRAFT_BALLOON
 use mode_ini_budget,        only: Budget_preallocate, Ini_budget
 USE MODE_INI_ONE_WAY_n
 USE MODE_IO
@@ -427,8 +428,6 @@ USE MODI_INI_AEROSET3
 USE MODI_INI_AEROSET4
 USE MODI_INI_AEROSET5
 USE MODI_INI_AEROSET6
-USE MODI_INI_AIRCRAFT_BALLOON
-USE MODI_INI_AIRCRAFT_BALLOON
 USE MODI_INI_BIKHARDT_n
 USE MODI_INI_CPL
 USE MODI_INI_DEEP_CONVECTION
diff --git a/src/MNH/write_balloonn.f90 b/src/MNH/write_balloonn.f90
index 295de8c3a151fc701259bba0cb1c1da27157ec84..974bde8804119bd6220300e0315669088ac8dac5 100644
--- a/src/MNH/write_balloonn.f90
+++ b/src/MNH/write_balloonn.f90
@@ -3,26 +3,18 @@
 !MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
 !MNH_LIC for details. version 1.
 !-----------------------------------------------------------------
-!     ###########################
-      MODULE MODI_WRITE_BALLOON_n
-!     ###########################
-!
-INTERFACE
-!
-SUBROUTINE WRITE_BALLOON_n(TPFILE)
-USE MODD_IO, ONLY: TFILEDATA
+!##########################
+MODULE MODE_WRITE_BALLOON_n
+!##########################
 !
 IMPLICIT NONE
-!
-TYPE(TFILEDATA),   INTENT(IN) :: TPFILE ! File characteristics
-!
-END SUBROUTINE WRITE_BALLOON_n
-!
-END INTERFACE
-!
-END MODULE MODI_WRITE_BALLOON_n
-!
-!
+
+PRIVATE
+
+PUBLIC :: WRITE_BALLOON_n
+
+CONTAINS
+
 !     ###################################
       SUBROUTINE WRITE_BALLOON_n(TPFILE)
 !     ###################################
@@ -59,17 +51,15 @@ END MODULE MODI_WRITE_BALLOON_n
 !!      Original    06/06/01 
 !  P. Wautelet 05/2016-04/2018: new data structures and calls for I/O
 !  P. Wautelet    06/2022: reorganize flyers
+!  P. Wautelet 25/08/2022: write balloon positions in netCDF4 files inside HDF5 groups
 !-------------------------------------------------------------------------------
 !
 !*       0.    DECLARATIONS
 !              ------------
 !
-USE MODD_AIRCRAFT_BALLOON
-USE MODD_GRID, ONLY: XLONORI, XLATORI
-USE MODD_IO,   ONLY: TFILEDATA
-USE MODD_LUNIT_n
+USE MODD_AIRCRAFT_BALLOON, only: NBALLOONS, TBALLOONS
+USE MODD_IO,               ONLY: TFILEDATA
 !
-USE MODE_GRIDPROJ
 !
 IMPLICIT NONE
 !
@@ -83,102 +73,219 @@ TYPE(TFILEDATA),   INTENT(IN) :: TPFILE ! File characteristics
 INTEGER :: JI
 
 DO JI = 1, NBALLOONS
-  IF ( TBALLOONS(JI)%LFLY ) CALL WRITE_LFI_BALLOON( TBALLOONS(JI) )
+  IF ( TBALLOONS(JI)%LFLY ) CALL WRITE_BALLOON_POSITION( TPFILE, TBALLOONS(JI) )
 END DO
-!
-!
-CONTAINS
-!
+
+END SUBROUTINE WRITE_BALLOON_n
 !-------------------------------------------------------------------------------
+
 !-------------------------------------------------------------------------------
-SUBROUTINE WRITE_LFI_BALLOON(TPFLYER)
+SUBROUTINE WRITE_BALLOON_POSITION( TPFILE, TPFLYER )
 !
+#ifdef MNH_IOCDF4
+use NETCDF,              only: NF90_DEF_GRP, NF90_GLOBAL, NF90_INQ_NCID, NF90_NOERR, NF90_PUT_ATT
+#endif
+
+USE MODD_AIRCRAFT_BALLOON
 use modd_field,          only: tfieldmetadata, TYPEREAL
+USE MODD_GRID,           ONLY: XLONORI, XLATORI
+use modd_io,             only: isp, tfiledata
+#ifdef MNH_IOCDF4
+use modd_precision,      only: CDFINT
+#endif
+
+USE MODE_GRIDPROJ,       ONLY: SM_LATLON
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
-!
+#ifdef MNH_IOCDF4
+use mode_io_tools_nc4,   only: IO_Err_handle_nc4
+#endif
+use mode_msg
+
+TYPE(TFILEDATA),    INTENT(IN) :: TPFILE ! File characteristics
 TYPE(TBALLOONDATA), INTENT(IN) :: TPFLYER
 !
 !
 !*       0.2   Declarations of local variables
 !
+#ifdef MNH_IOCDF4
+integer(kind=CDFINT) :: igroupid
+integer(kind=CDFINT) :: istatus
+#endif
 REAL                 :: ZLAT          ! latitude of the balloon
 REAL                 :: ZLON          ! longitude of the balloon
+type(tfiledata)      :: tzfile
 TYPE(TFIELDMETADATA) :: TZFIELD
-!
-!
-CALL SM_LATLON(XLATORI,XLONORI,  &
-     TPFLYER%XX_CUR,TPFLYER%XY_CUR,ZLAT,ZLON)
-!
-!
-TZFIELD = TFIELDMETADATA(                  &
-  CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LAT', &
-  CSTDNAME   = '',                         &
-  CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LAT', &
-  CUNITS     = 'degree',                   &
-  CDIR       = '--',                       &
-  CCOMMENT   = '',                         &
-  NGRID      = 0,                          &
-  NTYPE      = TYPEREAL,                   &
-  NDIMS      = 0,                          &
-  LTIMEDEP   = .TRUE.                      )
-CALL IO_Field_write(TPFILE,TZFIELD,ZLAT)
-!
-TZFIELD = TFIELDMETADATA(                  &
-  CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LON', &
-  CSTDNAME   = '',                         &
-  CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LON', &
-  CUNITS     = 'degree',                   &
-  CDIR       = '--',                       &
-  CCOMMENT   = '',                         &
-  NGRID      = 0,                          &
-  NTYPE      = TYPEREAL,                   &
-  NDIMS      = 0,                          &
-  LTIMEDEP   = .TRUE.                      )
-CALL IO_Field_write(TPFILE,TZFIELD,ZLON)
-!
-TZFIELD = TFIELDMETADATA(                  &
-  CMNHNAME   = TRIM(TPFLYER%CTITLE)//'ALT', &
-  CSTDNAME   = '',                         &
-  CLONGNAME  = TRIM(TPFLYER%CTITLE)//'ALT', &
-  CUNITS     = 'm',                        &
-  CDIR       = '--',                       &
-  CCOMMENT   = '',                         &
-  NGRID      = 0,                          &
-  NTYPE      = TYPEREAL,                   &
-  NDIMS      = 0,                          &
-  LTIMEDEP   = .TRUE.                      )
-CALL IO_Field_write(TPFILE,TZFIELD,TPFLYER%XZ_CUR)
-!
-TZFIELD = TFIELDMETADATA(                      &
-  CMNHNAME   = TRIM(TPFLYER%CTITLE)//'WASCENT', &
-  CSTDNAME   = '',                             &
-  CLONGNAME  = TRIM(TPFLYER%CTITLE)//'WASCENT', &
-  CUNITS     = 'm s-1',                        &
-  CDIR       = '--',                           &
-  CCOMMENT   = '',                             &
-  NGRID      = 0,                              &
-  NTYPE      = TYPEREAL,                       &
-  NDIMS      = 0,                              &
-  LTIMEDEP   = .TRUE.                          )
-CALL IO_Field_write(TPFILE,TZFIELD,TPFLYER%XWASCENT)
-!
-TZFIELD = TFIELDMETADATA(                  &
-  CMNHNAME   = TRIM(TPFLYER%CTITLE)//'RHO', &
-  CSTDNAME   = '',                         &
-  CLONGNAME  = TRIM(TPFLYER%CTITLE)//'RHO', &
-  CUNITS     = 'kg m-3',                   &
-  CDIR       = '--',                       &
-  CCOMMENT   = '',                         &
-  NGRID      = 0,                          &
-  NTYPE      = TYPEREAL,                   &
-  NDIMS      = 0,                          &
-  LTIMEDEP   = .TRUE.                      )
-CALL IO_Field_write(TPFILE,TZFIELD,TPFLYER%XRHO)
-!
-!
-!
-END SUBROUTINE WRITE_LFI_BALLOON
+
+CALL SM_LATLON( XLATORI, XLONORI, TPFLYER%XX_CUR, TPFLYER%XY_CUR, ZLAT, ZLON )
+
+#ifdef MNH_IOLFI
+IF ( TPFILE%CFORMAT == 'LFI' .OR. TPFILE%CFORMAT == 'LFICDF4' ) THEN
+  ! Write current balloon position for LFI files (netCDF uses an other structure)
+  TZFILE = TPFILE
+  TZFILE%CFORMAT = 'LFI'
+
+  TZFIELD = TFIELDMETADATA(                   &
+    CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LAT', &
+    CSTDNAME   = '',                          &
+    CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LAT', &
+    CUNITS     = 'degree',                    &
+    CDIR       = '--',                        &
+    CCOMMENT   = '',                          &
+    NGRID      = 0,                           &
+    NTYPE      = TYPEREAL,                    &
+    NDIMS      = 0,                           &
+    LTIMEDEP   = .TRUE.                       )
+  CALL IO_Field_write(TZFILE,TZFIELD,ZLAT)
+
+  TZFIELD = TFIELDMETADATA(                   &
+    CMNHNAME   = TRIM(TPFLYER%CTITLE)//'LON', &
+    CSTDNAME   = '',                          &
+    CLONGNAME  = TRIM(TPFLYER%CTITLE)//'LON', &
+    CUNITS     = 'degree',                    &
+    CDIR       = '--',                        &
+    CCOMMENT   = '',                          &
+    NGRID      = 0,                           &
+    NTYPE      = TYPEREAL,                    &
+    NDIMS      = 0,                           &
+    LTIMEDEP   = .TRUE.                       )
+  CALL IO_Field_write(TZFILE,TZFIELD,ZLON)
+
+  TZFIELD = TFIELDMETADATA(                   &
+    CMNHNAME   = TRIM(TPFLYER%CTITLE)//'ALT', &
+    CSTDNAME   = '',                          &
+    CLONGNAME  = TRIM(TPFLYER%CTITLE)//'ALT', &
+    CUNITS     = 'm',                         &
+    CDIR       = '--',                        &
+    CCOMMENT   = '',                          &
+    NGRID      = 0,                           &
+    NTYPE      = TYPEREAL,                    &
+    NDIMS      = 0,                           &
+    LTIMEDEP   = .TRUE.                       )
+  CALL IO_Field_write(TZFILE,TZFIELD,TPFLYER%XZ_CUR)
+
+  TZFIELD = TFIELDMETADATA(                       &
+    CMNHNAME   = TRIM(TPFLYER%CTITLE)//'WASCENT', &
+    CSTDNAME   = '',                              &
+    CLONGNAME  = TRIM(TPFLYER%CTITLE)//'WASCENT', &
+    CUNITS     = 'm s-1',                         &
+    CDIR       = '--',                            &
+    CCOMMENT   = '',                              &
+    NGRID      = 0,                               &
+    NTYPE      = TYPEREAL,                        &
+    NDIMS      = 0,                               &
+    LTIMEDEP   = .TRUE.                           )
+  CALL IO_Field_write(TZFILE,TZFIELD,TPFLYER%XWASCENT)
+
+  TZFIELD = TFIELDMETADATA(                   &
+    CMNHNAME   = TRIM(TPFLYER%CTITLE)//'RHO', &
+    CSTDNAME   = '',                          &
+    CLONGNAME  = TRIM(TPFLYER%CTITLE)//'RHO', &
+    CUNITS     = 'kg m-3',                    &
+    CDIR       = '--',                        &
+    CCOMMENT   = '',                          &
+    NGRID      = 0,                           &
+    NTYPE      = TYPEREAL,                    &
+    NDIMS      = 0,                           &
+    LTIMEDEP   = .TRUE.                       )
+  CALL IO_Field_write(TZFILE,TZFIELD,TPFLYER%XRHO)
+END IF
+#endif
+
+#ifdef MNH_IOCDF4
+IF ( TPFILE%CFORMAT == 'NETCDF4' .OR. TPFILE%CFORMAT == 'LFICDF4' ) THEN
+  ! Write current balloon position for netCDF files
+  ! Each balloon position is written inside an HDF5 group
+  TZFILE = TPFILE
+  TZFILE%CFORMAT = 'NETCDF4'
+
+  if ( isp == tzfile%nmaster_rank ) then
+    istatus = NF90_INQ_NCID( tzfile%nncid, Trim( tpflyer%ctitle ), igroupid )
+    if ( istatus == NF90_NOERR ) then
+      ! The group already exists (should not)
+      call Print_msg( NVERB_WARNING, 'IO', 'WRITE_BALLOON_POSITION', 'group '// Trim( tpflyer%ctitle ) // ' already exists' )
+    else
+      ! Create the group
+      istatus = NF90_DEF_GRP( tzfile%nncid, Trim( tpflyer%ctitle ), igroupid )
+      if ( istatus /= NF90_NOERR ) &
+        call IO_Err_handle_nc4( istatus, 'WRITE_BALLOON_POSITION', 'NF90_DEF_GRP', 'for ' // Trim( tpflyer%ctitle ) )
+
+      ! Add a comment attribute
+      istatus = NF90_PUT_ATT( igroupid, NF90_GLOBAL, 'comment', 'Current position of balloon '// Trim( tpflyer%ctitle ) )
+      if (istatus /= NF90_NOERR ) &
+        call IO_Err_handle_nc4( istatus, 'WRITE_BALLOON_POSITION', 'NF90_PUT_ATT', 'comment for '// Trim( tpflyer%ctitle ) )
+    end if
+  end if
+
+  tzfile%nncid = igroupid
+
+  TZFIELD = TFIELDMETADATA(  &
+    CMNHNAME   = 'LAT',      &
+    CSTDNAME   = '',         &
+    CLONGNAME  = 'LAT',      &
+    CUNITS     = 'degree',   &
+    CDIR       = '--',       &
+    CCOMMENT   = 'latitude', &
+    NGRID      = 0,          &
+    NTYPE      = TYPEREAL,   &
+    NDIMS      = 0,          &
+    LTIMEDEP   = .TRUE.      )
+  CALL IO_Field_write(TZFILE,TZFIELD,ZLAT)
+
+  TZFIELD = TFIELDMETADATA(   &
+    CMNHNAME   = 'LON',       &
+    CSTDNAME   = '',          &
+    CLONGNAME  = 'LON',       &
+    CUNITS     = 'degree',    &
+    CDIR       = '--',        &
+    CCOMMENT   = 'longitude', &
+    NGRID      = 0,           &
+    NTYPE      = TYPEREAL,    &
+    NDIMS      = 0,           &
+    LTIMEDEP   = .TRUE.       )
+  CALL IO_Field_write(TZFILE,TZFIELD,ZLON)
+
+  TZFIELD = TFIELDMETADATA(  &
+    CMNHNAME   = 'ALT',      &
+    CSTDNAME   = '',         &
+    CLONGNAME  = 'ALT',      &
+    CUNITS     = 'm',        &
+    CDIR       = '--',       &
+    CCOMMENT   = 'altitude', &
+    NGRID      = 0,          &
+    NTYPE      = TYPEREAL,   &
+    NDIMS      = 0,          &
+    LTIMEDEP   = .TRUE.      )
+  CALL IO_Field_write(TZFILE,TZFIELD,TPFLYER%XZ_CUR)
+
+  TZFIELD = TFIELDMETADATA(               &
+    CMNHNAME   = 'WASCENT',               &
+    CSTDNAME   = '',                      &
+    CLONGNAME  = 'WASCENT',               &
+    CUNITS     = 'm s-1',                 &
+    CDIR       = '--',                    &
+    CCOMMENT   = 'ascent vertical speed', &
+    NGRID      = 0,                       &
+    NTYPE      = TYPEREAL,                &
+    NDIMS      = 0,                       &
+    LTIMEDEP   = .TRUE.                   )
+  CALL IO_Field_write(TZFILE,TZFIELD,TPFLYER%XWASCENT)
+
+  TZFIELD = TFIELDMETADATA(     &
+    CMNHNAME   = 'RHO',         &
+    CSTDNAME   = '',            &
+    CLONGNAME  = 'RHO',         &
+    CUNITS     = 'kg m-3',      &
+    CDIR       = '--',          &
+    CCOMMENT   = 'air density', &
+    NGRID      = 0,             &
+    NTYPE      = TYPEREAL,      &
+    NDIMS      = 0,             &
+    LTIMEDEP   = .TRUE.         )
+  CALL IO_Field_write(TZFILE,TZFIELD,TPFLYER%XRHO)
+END IF
+#endif
+
+END SUBROUTINE WRITE_BALLOON_POSITION
 !-------------------------------------------------------------------------------
-!
-!
-END SUBROUTINE WRITE_BALLOON_n
+
+END MODULE MODE_WRITE_BALLOON_n
diff --git a/src/MNH/write_lfin.f90 b/src/MNH/write_lfin.f90
index 48184083922428bf61b4d506a6b50a17b959ca0c..c1fdfcd2c59835c512bff72284523dff8bb05a92 100644
--- a/src/MNH/write_lfin.f90
+++ b/src/MNH/write_lfin.f90
@@ -268,13 +268,13 @@ USE MODE_MODELN_HANDLER
 USE MODE_MPPDB
 USE MODE_MSG
 USE MODE_TOOLS, ONLY: UPCASE
+USE MODE_WRITE_BALLOON_n, ONLY: WRITE_BALLOON_n
 
 USE MODI_CH_AER_REALLFI_n
 USE MODI_DUST_FILTER
 USE MODI_DUSTLFI_n
 USE MODI_SALT_FILTER
 USE MODI_SALTLFI_n
-USE MODI_WRITE_BALLOON_n
 USE MODI_WRITE_LB_n
 
 IMPLICIT NONE